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

 找回密码
 加入VME

QQ登录

只需一步,快速开始

搜索
查看: 1876|回复: 5

[闲聊] OA多人模式下的问题(英文版)

[复制链接]
发表于 2010-11-29 19:14:05 | 显示全部楼层 |阅读模式
有懂的帮给翻译下

Multiplayer scripting
From Bohemia Interactive Community
Jump to: navigation, search
Contents [hide]
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

[edit]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.

[edit]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).

[edit]Local and Global Scripting Commands
Each scripting command can be described as either local or global. (more on this)

[edit]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.

; at this point in the script, everyone except the server will exit
?(!isServer): exit
; only execute this function on the server
?(isServer): call _fnSendMsg
; OFP example: all game logic objects are local to the server at all times,
; so by placing a reference game logic we get the equivalent of isServer
; this code is deprecated in ArmA
?(!local someGameLogic): exit
; exit the script unless you are a client in _vehicle
?(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)

[edit]Examples
[edit]Single-shot event
; init.sqs
; start client and server monitoring scripts
[] exec "serverScript.sqs"
[] exec "clientScript.sqs"
; serverScript.sqs
; this server-side script waits for a truck to come within 50m of the flag,
; then broadcasts a message to each client and exits
?(!isServer): exit
#loop
~1
?(TheTruck distance TheFlag < 50): goto "send"
goto "loop"
#send
TruckInArea = true; publicVariable "TruckInArea"
exit
; clientScript.sqs
; this client-side script waits for the server to broadcast a message,
; then displays a message and exits
@TruckInArea
hint "Truck is near the flag!"
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.

[edit]Repeating event
; init.sqs
; start client and server monitoring scripts
[] exec "serverScript.sqs"
[] exec "clientScript.sqs"
; serverScript.sqs
; broadcast a message every time TheMan comes within
; 50m of TheFlag
?(!isServer): exit
#loop
@TheMan distance TheFlag < 50
ManIsHere = true; publicVariable "ManIsHere"
@TheMan distance TheFlag > 50
goto "loop"
; clientScript.sqs
; display a message when ManIsDead is received
#loop
@ManIsHere
ManIsHere = false
hint "Man is near the flag!"
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.

[edit]Multiple events
; init.sqs
; initialize flag system
; start client and server monitoring scripts
NO_CAPTURE = 0
WEST_CAPTURE = 1
EAST_CAPTURE = 2
RES_CAPTURE = 3
SectorStatus = NO_CAPTURE
[] exec "serverScript.sqs"
[] exec "clientScript.sqs"
; serverScript.sqs
; broadcast a message every time someone takes TheFlag
?(!isServer): exit
#loop
@!isNull (flagOwner TheFlag)
?(side (flagOwner TheFlag) == WEST): goto "westCap"
?(side (flagOwner TheFlag) == EAST): goto "eastCap"
?(side (flagOwner TheFlag) == RESISTANCE): goto "guerCap"
; if we are here, bad side for flag owner
goto "resetflag"
#westCap
SectorStatus = WEST_CAPTURE; publicVariable "SectorStatus"
TheFlag setFlagSide WEST
goto "resetflag"
#eastCap
SectorStatus = EAST_CAPTURE; publicVariable "SectorStatus"
TheFlag setFlagSide EAST
goto "resetflag"
#guerCap
SectorStatus = RES_CAPTURE; publicVariable "SectorStatus"
TheFlag setFlagSide RESISTANCE
#resetflag
TheFlag setFlagOwner objNull
goto "loop"
; clientScript.sqs
; display a message when the sector is captured
#loop
@SectorStatus != NO_CAPTURE
?(SectorStatus == WEST_CAPTURE): hint "West captured the sector!"; goto "reset"
?(SectorStatus == EAST_CAPTURE): hint "East captured the sector!"; goto "reset"
?(SectorStatus == RES_CAPTURE): hint "Resistance captured the sector!"; goto "reset"
#reset
SectorStatus = NO_CAPTURE
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.

[edit]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.

[edit]JIP
There are also the matter of what happens if a client is disconnected. With ArmA you have the opposite issue introduced by JIP - will that client have a state that will work with the rest?

There are a few ways of affecting the other computers: -publicVariable -CoC Network services -...

[edit]Addon Scripting
(todo)

This article is a stub. You can help BI Community Wiki by expanding it.
Retrieved from "http://community.bistudio.com/wiki/Multiplayer_scripting"
 楼主| 发表于 2010-11-29 19:14:43 | 显示全部楼层
发表于 2010-11-29 23:45:27 | 显示全部楼层
标题:多人模式脚本编辑

翻译完毕……………………
 楼主| 发表于 2010-11-29 23:49:37 | 显示全部楼层
回复 Alex.XP 的帖子

嗯。。很好。。
下面呢?
发表于 2010-11-29 23:52:01 | 显示全部楼层
bym101 发表于 2010-11-29 23:49
回复 Alex.XP 的帖子

嗯。。很好。。

下面没有了………………

请原谅我在广州出差天天被客户沟通和.NET代码折磨无力翻译……

这个你可以先参照下……
http://wiki.huhao.name/%e6%ad%a6 ... 2%ad2.MainPage.ashx
 楼主| 发表于 2010-11-30 12:36:06 | 显示全部楼层
恭喜XP事业有成,财源滚滚
您需要登录后才可以回帖 登录 | 加入VME

本版积分规则

小黑屋|中国虚拟军事网

GMT+8, 2024-5-15 16:52

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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