中国虚拟军事网(VME)- 专注于武装突袭系列虚拟军事游戏

 找回密码
 加入VME

QQ登录

只需一步,快速开始

搜索
查看: 4555|回复: 9

[教程] 多人任务编写指南

  [复制链接]
发表于 2012-8-18 12:03:54 | 显示全部楼层 |阅读模式
本帖最后由 qevhytpl 于 2012-12-29 22:22 编辑

我简单翻译了下官方的东西,大概了解了一下多人任务的编辑情况
1 Introduction 介绍
2 Common Multiplayer Scripting Problems 常见的多人任务脚本问题
3 Local and Global Scripting Commands 局部与全局脚本命令
4 Server-Side Scripting 服务器端脚本
4.1 Examples 举例
4.1.1 Single-shot event 单发事件
4.1.2 Repeating event 重复事件
4.1.3 Multiple events 多人事件
5 Testing Environment 测试环境
6 JIP
7 Addon Scripting 插件脚本

Introduction   
Scripting for multiplayer missions is difficult for many scripters and mission editors to understand. Systems that work perfectly in the mission editor environment can fail miserably when run on a dedicated server, resulting in an inconsistent gameplay experience for clients and frustration for the editor. The keys to success at multiplayer scripting are learning the properties of every scripting command, devising ironclad methods for propagating messages, and testing in an appropriate environment.
    对于许多程序员与编辑员来说,多人任务脚本相当难于理解。任务编辑器里可以完美运行的系统往往在专属服务器中莫名其妙的失败。结果客户端用户会有前后矛盾的、不稳定的游戏体验,而带给编辑者的则是挫折感。多人任务脚本书写成功的关键是:充分的领悟各个命令、为信息传送设置牢固而稳定的方式方法且在适宜的环境下不断测试。

Common Multiplayer Scripting Problems
Many scripts fail in a multiplayer environment because they rely on inconsistent variables. Inconsistent variables are conditions that are not guaranteed to be the same for each client in a multiplayer game:
     诸多脚本在多人联机环境下失败的原因是他们都依赖一些不稳定变量,这些变量可能会前后矛盾。这些变量通常不能保证所有的客户端都拥有相同的运行情况。
•        Properties of soldiers, vehicles, or other objects (especially their position and velocity) 人员、载具、其他物品的装备(特别是他们的位置与速度)
•        The time command 时间命令
•        Event handlers that are not executed globally 不能全局执行的事件处理程序
•        Any random value 所有随机变量
•        A unit taking a flag 夺旗单位
•        Many others 其他许多问题

   Any scripted system relying on inconsistent variables (without proper multiplayer scripting techniques) will result in unpredictable states for each client at any given time. Common symptoms for clients include seeing different scores, seeing the mission end at different times, missing hint or radio messages, and seeing different states for flags and other objectives.
       任何依赖于不稳定变量的脚本系统(没有完善的多人脚本书写技术)将在任何给定时间、每一个客户端造成不可预知的错误。常见症状如:客户端显示不同的分数,在不同的时间看到任务结局,丢失提示信息与无线电信息,看到不同的目标状态等诸多不一致的情况。
    Another reason for scripts failing in a multiplayer environment is failure to account for global scripting commands. For example, a simple script that respawns a vehicle using createVehicle may work perfectly in the mission editor, but when run on a dedicated server, a new vehicle is created for every client. That means on a full 64 player server, 65 new vehicles will be created when a vehicle respawns (one for each client and one for the server entity). This kind of error will make a mission unplayable very quickly (especially when someone gets the bright idea of destroying all the extra vehicles, causing them to reproduce exponentially).
      多人环境下脚本失败的另一个原因是错误理解全局脚本命令。例如一个简单的产生一辆新载具的脚本可以在编辑器里完美运行,但是当在专属服务器里,每个客户端都会产生一个新载具。那就意味着64个客户端,会产生65个载具。这种错误会造成整个任务迅速崩溃(特别是有人想出个炸毁所有车辆的点子,这往往会造成车辆的指数级增加)
   
Local and Global Scripting Commands全局与局部脚本命令
Each scripting command can be described as either local or global. (more on this)
每一个脚本命令都可以被运用于全局或者局部。

Server-Side Scripting 服务器端脚本
    The best way to solve a problem in which you must rely on an inconsistent variable is to delegate the responsibility to one entity. The only entity we can trust for objective-related duties is the server. The server entity is guaranteed to be present for the length of the mission, and is the only entity with a "true" game state. By making sure that the server is the only entity tracking the status of objectives, we have a starting point for building a multiplayer-safe system.
     如果你一定要依赖不稳定变量,那么最好的办法就是你指定一个承担责任的实体来替换不稳定变量。在服务器,我们唯一可以信任的与目标相关的东西就是实体。服务器实体可以保证整个任务过程中持续的存在,并且只有实体关联着“实在”任务状态。在确定由实体关联目标状态的情况下,我们开始建立有运行保障的多人任务环境。


The most useful commands for controlling multiplayer scripts are local, isServer, and player.
控制多人任务脚本最有用的三个命令是local, isServer, 和 player。
  1. ; at this point in the script, everyone except the server will exit
  2. ?(!isServer): exit
复制代码
  1. ; only execute this function on the server
  2. ?(isServer): call _fnSendMsg
复制代码
  1. ; OFP example: all game logic objects are local to the server at all times,
  2. ; so by placing a reference game logic we get the equivalent of isServer
  3. ; this code is deprecated in ArmA
  4. ?(!local someGameLogic): exit
复制代码
  1. ; exit the script unless you are a client in _vehicle
  2. ?(vehicle player != _vehicle): exit
复制代码
A multiplayer scripter must be fully aware of who is executing every line of code. No code should be executed unless it is necessary for the mission to function. For example, in a sector control mission, a client doesn't need to keep track of who is in a sector when the server is the point of reference for capturing sectors and updating each team's score. Instead, clients should run routines that "listen" for changes in variables broadcast by the server.
       多人任务编辑员必须充分意识到谁在执行每一句代码。除非任务需要,否则不要执行多余的代码。例如一个夺占任务,当服务器正在判定占领方并且更新各方分数时,客户端没有必要跟踪谁是占领者。此时的客户端应当常规运行,获得服务器发送的消息。
publicVariable is the preferred method of propagating messages from the server to all clients. (more about pV)
公共变量是从服务器向客户端传送信息的优先方法。

举例
Single-shot event 单次事件
  1. ; init.sqs
  2. ; start client and server monitoring scripts
  3. [] exec "serverScript.sqs"
  4. [] exec "clientScript.sqs"
复制代码
  1. ; serverScript.sqs
  2. ; this server-side script waits for a truck to come within 50m of the flag,
  3. ; then broadcasts a message to each client and exits
  4. ?(!isServer): exit
  5. #loop
  6. ~1
  7. ?(TheTruck distance TheFlag < 50): goto "send"
  8. goto "loop"
  9. #send
  10. TruckInArea = true; publicVariable "TruckInArea"
  11. exit
复制代码
  1. ; clientScript.sqs
  2. ; this client-side script waits for the server to broadcast a message,
  3. ; then displays a message and exits
  4. @TruckInArea
  5. hint "Truck is near the flag!"
  6. exit
复制代码
The example above is a "single-shot" server-triggered event. Note that the client-side script is also run by the server. Otherwise, the system could break on non-dedicated servers. Also, an undeclared variable will never return true, so we don't need to declare TruckInArea ahead of time.
      上面的例子是服务器一次触发事件。注意:客户端脚本也由服务器运行。否则,系统在非专属服务器运行时可能会崩溃。另外一个非发布变量(undeclared variable)不会返回true值,所以我们不需要提前宣布TruckInArea。

Repeating event 重复事件
  1. ; init.sqs
  2. ; start client and server monitoring scripts
  3. [] exec "serverScript.sqs"
  4. [] exec "clientScript.sqs"
复制代码
  1. ; serverScript.sqs
  2. ; broadcast a message every time TheMan comes within
  3. ; 50m of TheFlag
  4. ?(!isServer): exit
  5. #loop
  6. @TheMan distance TheFlag < 50
  7. ManIsHere = true; publicVariable "ManIsHere"
  8. @TheMan distance TheFlag > 50
  9. goto "loop"
复制代码
  1. ; clientScript.sqs
  2. ; display a message when ManIsDead is received
  3. #loop
  4. @ManIsHere
  5. ManIsHere = false
  6. hint "Man is near the flag!"
  7. goto "loop"
复制代码
The example above is a repeating server-triggered event. Every time the server sees TheMan approaching TheFlag, ManIsHere is set to true and broadcast. Each client waits for ManIsHere to become true, then sets it to false to prepare for the next broadcast. Note that each client resets the variable locally; setting ManIsHere to false without a following publicVariable does not affect other clients or the server.
     上面的例子是服务器重复触发事件。每一次服务器发现TheMan靠近TheFlag,ManIsHere被设置为true和广播。每一个客户端等待ManIsHere变为“true”,然后设置失败并且准备下一次广播。注意:每个客户端在局部重新设置变量,将ManIsHere设为失败,公共变量会影响到服务器和客户端。

Multiple events 多人事件
  1. ; init.sqs
  2. ; initialize flag system
  3. ; start client and server monitoring scripts
  4. NO_CAPTURE = 0
  5. WEST_CAPTURE = 1
  6. EAST_CAPTURE = 2
  7. RES_CAPTURE = 3
  8. SectorStatus = NO_CAPTURE
  9. [] exec "serverScript.sqs"
  10. [] exec "clientScript.sqs"
复制代码
  1. ; serverScript.sqs
  2. ; broadcast a message every time someone takes TheFlag
  3. ?(!isServer): exit
  4. #loop
  5. @!isNull (flagOwner TheFlag)
  6. ?(side (flagOwner TheFlag) == WEST): goto "westCap"
  7. ?(side (flagOwner TheFlag) == EAST): goto "eastCap"
  8. ?(side (flagOwner TheFlag) == RESISTANCE): goto "guerCap"
  9. ; if we are here, bad side for flag owner
  10. goto "resetflag"
  11. #westCap
  12. SectorStatus = WEST_CAPTURE; publicVariable "SectorStatus"
  13. TheFlag setFlagSide WEST
  14. goto "resetflag"
  15. #eastCap
  16. SectorStatus = EAST_CAPTURE; publicVariable "SectorStatus"
  17. TheFlag setFlagSide EAST
  18. goto "resetflag"
  19. #guerCap
  20. SectorStatus = RES_CAPTURE; publicVariable "SectorStatus"
  21. TheFlag setFlagSide RESISTANCE
  22. #resetflag
  23. TheFlag setFlagOwner objNull
  24. goto "loop"
复制代码
  1. ; clientScript.sqs
  2. ; display a message when the sector is captured
  3. #loop
  4. @SectorStatus != NO_CAPTURE
  5. ?(SectorStatus == WEST_CAPTURE): hint "West captured the sector!"; goto "reset"
  6. ?(SectorStatus == EAST_CAPTURE): hint "East captured the sector!"; goto "reset"
  7. ?(SectorStatus == RES_CAPTURE): hint "Resistance captured the sector!"; goto "reset"
  8. #reset
  9. SectorStatus = NO_CAPTURE
  10. goto "loop"
复制代码
This is an example of using a single variable to trigger multiple exclusive events repeatedly. This time, the variable and a series of status constants (think of it like an enumerated list in C) must be declared in init.sqs before the monitor scripts begin. When a unit takes the flag, the server changes SectorStatus to the appropriate numerical value and broadcasts it. When the client sees that SectorStatus is no longer in the null state (NO_CAPTURE), it interprets the message and resets SectorStatus to prepare for the next message.
       一个使用单一变量重复触发多人特有事件的例子。这一次,在监控脚本开始运行前,变量与所有状态内容(think of it like an enumerated list in C)均需在init.sqs发布。当某单位夺旗,服务器将占领状态变化为相应的数值变量并且广播他。当客户端发现占领状态无人的情况(NO_CAPTURE)时,他打断消息,重新设置占领状态并且为下一次消息作准备。

Testing Environment  测试环境
     Most scripters will use a dedicated server for testing their scripts in multi player and 2 client machines. Some will run a copy of ArmA in -server mode on the same machine as a client. This is an ideal setup as you can make sure that what you're seeing on one client is the same on the other client. The purpose of this testing environment is to prepare a mission for public play on a dedicated server, which is the most common target for a multiplayer mission.
      大多数程序员使用专属服务器在多人状态下和两个客户端机器下测试他们的脚本。也有些人是在作为一个客户端的机器上以服务器模式运行武装突袭复本。这个主意可以保证让你与其他客户端看到相同的情况。做这样的测试是为了准备多人联机任务,这是多人任务的目标。
Some people will try and test their scripts by hosting a server in game, and while this might work it can sometimes produce inaccurate results when you transfer the missions over to a dedicated server.
      有些人是通过自己在任务中充当主机来测试脚本的,然而这样的测试可能会在你传输任务至专属服务器时发生错误。
A faster testing environment is described in the article here. You need to work disconnected from the Internet, or using the trick described there.
      参见官网
    JIP(Join In Progress)
      There are also the matter of what happens if a client is disconnected. This feature allows you to join in a multi player match/game/mission while it is running, you don't have to wait for the next mission as you do in Operation Flashpoint. To disable the JIP on the server, admin simply disables any AI (playable slots) on the role selection screen. However, if respawn is enabled in the mission, it's still possible to get into the mission.

    客户端掉线是个麻烦事情。这个特性可以允许你在任务或者比赛运行进直接加入其中,而不是像闪点那样要等到下一个任务开始时才能加入。如果想禁用掉服务器端的JIP功能,管理员只需要把选择角色界面的playable AI点掉即可,然而如果任务允许重生,将不可能再进入任务。


多人任务编辑技术补充
1.
  1. if (!isServer) exitWith {};
复制代码
should prevent the script from being executed if it's not a server or a host.
2.Local commands are only run on clients (or the server) that actually executed the command. If every client executed the command, the result is that it is run once on each client. If only one or some of the clients executed the command, the result is that the clients that did not execute the command will not see any of its effects.

Global commands are broadcast over the network to every client regardless of which client (or server) executed the command. If a single client executes a global command, it is run once on every client (unlike a local command, which would only be run once on that client). If multiple clients execute a global command, then it is run multiple times on each client (one time per client or server that executed it) because it is broadcast every time it is executed. This leads to generally undesirable results, and with a high player count, it can lead to disastrous, server-annihilating results.

The general rule-of-thumb for MP mission design is to run local commands once on each client and global commands once only on the server (because it is a global command, the result will in turn be broadcast to all clients). As Carl mentioned, isServer is the easiest way to do a server check. You can either do it as he showed to make a whole script run only on the server, or you can use an "if (isServer) then..." control structure if you only want to run a few lines on the server and allow the rest to be run everywhere. This is useful if, for example, you have a mixture of local and global commands, or if you want to come up with a random number but want that number to be consistent across all clients.

3.Commands only run on the computer that ran the command, however some commands result in things that end up getting broadcasted on the network (for example: creating a vehicle, setting an object's position, setting damage).

Some commands will take no affect if you try to run them on a machine that is not controlling the unit (for example a client running an addWeapon command for an AI solder that is not under his command will not work as that AI soldier is controlled by the server, or in other words local to the server).

init.sqf and all units' init lines run on all machines.

Triggers run on all machines that have their condition set to "true", which for some triggers may be for all machines at the same time, while for more complicated conditions or in case of desync a trigger can be true only for some machines and not for others. You can even create a trigger by a script that runs only on one machine and that trigger will then only exist for that one machine and thus will only activate on that specific machine when its condition becomes true, which is useful for radio triggers where you want to know who clicked the trigger.

In order to run something only once, such as spawning a fixed amount of AI, you need to use if (isServer) then {....}; and replace the .... with the code that is spawning the AI. That is, in SQF format, which you really should use as it's much easier to write and read.
4.对于服务器的个人理解
The general rule-of-thumb for MP mission design is to run local commands once on each client and global commands once only on the server (because it is a global command, the result will in turn be broadcast to all clients).
多人任务编辑的一般规律是:各客户端分别运行局部命令一次,服务器运行全局命令一次(运行结果广播给客户端)

    对于一般规律的理解:同一个命令服务器运行了,各个客户端也运行了,这个命令从整个宏观的角度讲只运行了一次,服务器与客户端运行的情况是完全相同的。什么叫运行情况完全相同?比如在A点生成一个炮弹,服务器在A生成了一发炮弹,各个客户端也在A点生成了一发炮弹,理论上讲,在宏观的情况下只生成了一发炮弹。命令运行了一次,只不过在服务器运行就叫做全局命令(全局运行),各个客户端就叫做局部命令了(局部运行)。也就是说无论服务器还是客户端都 必须运行命令,服务器要做的一点工作就是把命令的运行结果告诉各个客户端,像上面谈到的生成炮弹,在A点生成炮弹而不是别的地方。这一点很重要。
    在多人任务编写的脚本书写中有一条重要的命令就是服务器判定
  1. if (!isServer) exitWith {};
复制代码
例如一个生成飞机的脚本,如果你不在脚本开始加上这条命令,会出现严重bug,不加服务器判定的脚本会被服务器与各个客户端分别运行,结果是服务器生成一架飞机,各个客户端分别生成一架飞机,毫无疑问,本来应该生成一架飞机,结果生成了(服务器+各个客户端)架飞机。
然而我却碰到一个奇怪案例,使的以上推理可能是错的
  1. if (!isServer) exitWith {};
  2. //生成飞机,初始化状态
  3. ruPilot = creategroup EAST;
  4. ruplane = createVehicle ["Mi17_rockets_RU",rum,[], 0, "FLY"];
  5. ruplane setPos [(getPos rum select 0),(getPos rum select 1),500];
  6. //生成组;
  7. RU_P = ruPilot  createUnit ["MVD_Soldier_GL",rum,[],1, "NONE"];
  8. //组进入飞机;
  9. RU_P moveinDriver ruplane;
  10. //第一个路点,调整飞行高度与速度;
  11. _pos1 = getMarkerPos "RUA";
  12. _wp = ruPilot addWaypoint [_pos1, 0];
  13. _wp setWaypointStatements["true","nul=[]execVM'land.sqf';"];
  14. ruPlane flyinheight 150;
  15. ruPlane setVelocity [70,0,0];
复制代码
  1. if (!isServer) exitWith {};
  2. QBB removeAction HDQB;
  3. titleText ["车臣的机械化部队将于20分钟后通过城堡北面的Vyshnoye小镇!", "PLAIN"];
  4. sleep 2;
  5. titleText ["766.0高地的东面有大批匪军出没,他们企图越过766.0高地!", "PLAIN"];
  6. sleep 3;
  7. deleteVehicle QBB;
  8. sleep 60;
  9. tank111= createVehicle ["Mi24_V",m1_1,[], 0, "NONE"];
复制代码
先给出两个脚本

说一下这两个脚本在实际状态下的运行情况
单机下完美运行
自建主机情况下完美运行
服务器情况下脚本1完全运行,脚本2运行失败
服务器情况下均去掉服务器判定语句,脚本1运行后生成两架直升机(我是专属服务加一个客户端的情况),脚本2运行,并且只产生了一架飞机(注意我前面说的话,理论上讲应该生成两架)。然而虽然脚本2运行了但是路点中的判定条件(tank111 distance m1_1<200)却没有转为TRUE。在自建主机的情况下脚本2运行正常,距离判定也可以顺利转为TRUE。
原因是什么呢?!

5.Remember that many conditions work only in server. E.g. unit names are only in server side. To solve many problems, I would suggest to use separate scripts for clients without any conditions in them except publicvariables if needed.
I use it like this. In init.sqf I have:
  1. if (isnil("Var1")) then {Var1=false;};
复制代码
Then during mission a script (ran in server) changes it to true for all clients with:
  1. Var1=true;publicvariable "Var1";
复制代码
After that the variable "Var1" is true also for JIP-players and to the end of the mission unless you make the server change it back to false in the same way. This way you can trigger e.g. chatting, but disable it again so players (joined during playing) dont have all the outdated client stuff running superpositioned at mission start.
E.g. I have triggers for client scripts like this:
  1. Condition: Var1 && !(local server)
  2. On Act: _nul = []execVM "ClientScript1.sqf";
复制代码
The other challening part is to display tasks right for eneryone. For server and clients, you can use the previous methods, but for JIP-players you need this:

In init.sqf:
  1. waitUntil {!isNull player};
  2. //-1 not made, 0 created, 1 finished, 2 assigned, 3 failedif (VarOBJLZ==-1) then {};
  3. if (VarOBJLZ==0) then {
  4.           taskLZ = player createSimpleTask [Localize "STR_5OBJLZH"];        
  5.           taskLZ setSimpleTaskDescription [Localize "STR_5OBJLZ", Localize "STR_5OBJLZH", Localize "STR_5OBJLZW"];      
  6.           taskLZ setSimpleTaskDestination [10081.2,10312.5,0];      
  7.           player setCurrentTask taskLZ;  
  8.            };
  9. if (VarOBJLZ==1) then {
  10.           taskLZ = player createSimpleTask [Localize "STR_5OBJLZH"];
  11.           taskLZ setSimpleTaskDescription [Localize "STR_5OBJLZ", Localize "STR_5OBJLZH", Localize "STR_5OBJLZW"];
  12.           taskLZ setSimpleTaskDestination [10081.2,10312.5,0];      
  13.           taskLZ settaskstate "SUCCEEDED";        
  14.           };
  15. if (VarOBJLZ==2) then {};if (VarOBJLZ==3) then {};
复制代码
So when new player joins, he gets "taskLZ"-task created. Unless server have changed VarOBJLZ to 1 (with VarOBJLZ=1;
publicvariable "VarLZ"; ), when the joined player have the task created with "succeeded"-status.

Thats the way I have been creating my COOP-missions. I am also only learning MP scripting (so my way could include rookie stuff), but these methods should work right for dedicated and normal- servers.

6    The public variable
The public variable has to be used in Multiplayer games only, that’s why its explained in this chapter and not in the Scripting chapter. One can basically compare it with the global variable, although it’s nevertheless a little bit different. By using the public variable one makes a global variable become public. That means that the information will be sent from a client to all of the other ones and even to the Server or the Host also to execute the respective Action.

MR MURRAY的精典论述
   If one is playing a Multiplayer Mission, so the Client will be recognized as a local variable, what means that the global variable, which is meant for the whole Mission onto the whole Map, turns to a local one. This is why that all happens for all clients (player) individually. That all is not a Problem so long the respective units (Clients) has received fixed names. Because every Client, who is joining the Mission is receiving his values. But if the creator of a Mission wants to allocate a value to a variable, i.e. true or false, this will only take effect for the respective player who is executing such a trigger, waypoint etc. So this information now needs to be sent to all the other clients become to make the result of the caused action visible for every client.



7.心得
7.1一定弄清楚谁应该执行每一条指令!
7.2局部执行的指令,如果想要全局生效一定要告诉服务器!

8.心得
不加服务器判定的脚本将在局部运行,局部运行结果不会广播给服务器与客户端,不能全局生效。
服务器运行的命令通常全部可以全局生效。

9.
Hoping this makes anyone new to BIS scripting more aware of the relationships between
Local, Global, Player and Server



First thing
Game logics are "Only" local on the server, be it a player/server or a dedicated server
as an unwritten standard, most mission makers create a gamelogic and name it "Server"

when you are running the code
?(local server):
what you are actually stating is
Is the game logic named "server" local on this machine, if so, run the code that follows on from ":"

Typical switches are
for .sqs
  1. ?(local server):hint "I am the server machine"
  2. ?!(local server):hint "I am not the server machine"
  3. ? (local player):hint "I am a player machine"
  4. ?! (local player):hint "I am a dedicated server machine"


复制代码
for .sqf
  1. if (local server) then {hint "I am the server machine"};
  2. if (! local server) then {hint "I am not the server machine"};
  3. if (local player) then {hint "I am a player machine"};
  4. if (! local player) then {hint "I am a dedicated server machine"}
复制代码
Where and when to use these, is dependant on what code you are running and where you want the code to run

More often than not you will see the following at the very start of a script
  1. ?(Local server): exit
  2. if(local server)then{exit};
  3. ?(local player): exit
  4. if(local player)then{exit};
复制代码
These lines are used to stop the script from being run on certain machines

or, you can also initiate a script on either clients or server by using something like the following
  1. ?(Local server): [] exec "myscript.sqs
  2. ?(local player): [] exec "myscript.sqs
  3. or more correctly with arma, functions
  4. ?(Local server): [] execVM "myscript.sqf;
  5. ?(local player): [] execVM "myscript.sqf;

复制代码
Certain commands are local or global

Global commands
are commands that when run on 1 machine, every other machine is sent / receives that data

Local commands are commands that do not send data to other machines.

setpos, is actually a global command, which means only 1 machine needs to run this code, as all the other machines will receive the data of the objects new position and reposition it
If you run this code on all machines, then every machine will tell every ,machine where to setpos the object, and the last machine that runs the code, will be the one that overwrites the rest

"setdir" is local, meaning if you setdir an object on 1 machine, the others wont see it placed in the new direction, until some other code updates it

It takes time, but eventually you will discover which commands are local and which arent and the workarounds to create a global from a local

Eg, to make setdir into a global command, first setdir the object then setpos it, the setpos sends the direction of the object, thus setdir has been sent globally.

A new command that comes in both Global and local flavours is the setmarkerpos, with it's local varient SetmarkerposLocal

I hope that gives you a better understanding of the relationship between player/server/global/local


NB>> Up too and including the present version (1.05) "setpos" will not work with static objects, eg ammo crates etc, this i believe is a big and will be rectified in some future patch

10.       (一) if (local server) exitWith {};    --所有客户端运行 (如果是服务器,则退出,服务器退出,包括主机,客户端执行 )
       (二) if (! local server) exitWith {};    --服务器运行         (如果不是服务器(专属与非专属),则退出,客户端退出,服务器执行)
       (三) if (local player) exitWith {};   --专属服务器运行       (如果是客户端,则退出,客户端退出,专属服务器执行)
       (四) if (! local player) exitWith {};   --客户端运行               (如果不是客户端,则退出,专属服务器退出,客户端执行)
       (五)  if (! isServer) exitWith {};       --服务器(包括专属与非专属)运行     (如果不是服务器,则退出,客户端退出,服务器执行)
       (六)  if (! isDedicated) exitWith {};    --专属服务器运行    (如果不是专属服务器,则退出,客户端退出,主机也退出,专属服务器运行)
        问:如何让服务器运行,作为主机的客户端不运行?
回答:when you are hosting your are local to the server so that anything that happens on the server (eg. hints) also happens on your computer, whereas on a dedicated server you are not local to the server.



11.补充材料

It does make sense to have them running on all clients especially if they only affect local units. Many of the commands also only have local effects so running them only for the server wouldn't do much unless you send them to all clients from there.
How you prefer to do it is up to you.

I usually have any scripts that contain mission-logics, like checking triggers, objectives and such running only on the server.

Scripts that affect units, like adding equipment, giving orders or having any other direct influence on units are executed local for the respective player.

Scripts that allow the server to pass information to the players, messages, updated objectives, effects that should be visible to everyone... I run those on all machines, including the server (if its not dedicated).



You see, it really depends on the situation, there is no universal solution.








本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入VME

x

点评

翻译有奖  发表于 2012-9-21 16:57
 楼主| 发表于 2012-8-25 23:40:15 | 显示全部楼层
ji44664455 发表于 2012-8-19 01:37
建议你弄成一个教程   不要直接用文字打出来发出来

多人任务编辑比较复杂,我也只是在摸索阶段。
发表于 2012-8-26 10:15:53 | 显示全部楼层
无限感谢!
 楼主| 发表于 2012-8-26 20:02:52 | 显示全部楼层
hiddenzone 发表于 2012-8-26 10:15
无限感谢!

持续更新,有点乱,欢迎指正并且参加讨论。
发表于 2012-9-21 15:25:58 | 显示全部楼层
o-o 偶最近也在研究多人任务,感谢楼主资料哈
发表于 2012-9-21 16:55:03 | 显示全部楼层
JIP = Jump Inprocess Player         中途进入游戏的玩家
发表于 2014-6-20 10:42:55 | 显示全部楼层
非常感谢。。。
发表于 2014-6-20 16:49:35 | 显示全部楼层
虽然看不懂,但是貌似也明白了一些段秒。
 楼主| 发表于 2014-6-20 18:53:50 | 显示全部楼层
bym101 发表于 2014-6-20 16:49
虽然看不懂,但是貌似也明白了一些段秒。


这个不如FF版主写的好啊,有些问题我至今没有搞懂呢。
您需要登录后才可以回帖 登录 | 加入VME

本版积分规则

小黑屋|中国虚拟军事网

GMT+8, 2024-4-17 07:07

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表