SCAR (SCripting At Relic) is a LUA-based language used for scripting in-game action. While SCAR is used in many other Relic games, the implementation is often different, meaning functions and types may differ as well as the version of LUA used.
As of July 8th, 2009 there is no official SCAR documentation for Dawn of War 2 as there is for Company of Heroes. You should learn about LUA to understand the basics of SCAR. For DoW2 SCAR files can typically be identified by .ai, .scar or .lua extensions, however they are merely text files not binary files. Editing SCAR files is done using a text editor or a LUA IDE.
“In computer science, a subroutine or subprogram (also called procedure, method, function, or routine) is a portion of code within a larger program, which performs a specific task and is relatively independent of the remaining code.” -Wikipedia
In DoW2, SCAR functions can be used to create powerful mods by dynamically creating entities, slowing down game speed, applying modifiers, etc.
Relic extended many functions to LUA for use in SCAR scripting. There are several ways of finding out about these functions; one could either search the relevant files (DoW2.exe, SimEngine.dll) for strings that look like function names or one could use a disassembler and search the disassembled code for calls of the LUA binding function.
Setup_Player() in setup.scar
function Setup_Player(playerIndex, playerName, playerRace, team) if (scartype(team) ~= ST_NUMBER or team < 1 ) then fatal( "Setup_Player: team ID has to be a number starting from 1") end -- accept raw strings for now... convert them to LocString if (scartype(playerName) == ST_STRING) then playerName = LOC(playerName) end -- get player handle local playerId = World_GetPlayerAt( playerIndex ) -- set player name and race Setup_SetPlayerName(playerId, playerName) Setup_SetPlayerRace(playerId, World_GetRaceIndex(playerRace)) -- start the index from 0 if ( team ~= TEAM_NEUTRAL ) then team = team-1 end -- mod Setup_SetPlayerTeam(playerId, team) return playerId end
“A data type (or datatype) in programming languages is a set of values and the operations on those values.” -Wikipedia
LUA data types can be used, but SCAR adds some additional data types known as Scar Types (ST) that are, in most cases, pre-fixed with “ST_” such as ST_PLAYER.
followmanager.scar (1.3.2)
function FollowManager_AddGroup(sgroup1, sgroup2, distance)
if distance == nil then
distance = 5
end
if _FollowTable == nil then
_FollowTable = { }
end
table.insert(_FollowTable, {sgroup1 = sgroup1, sgroup2 = sgroup2, distance = distance} )
if Rule_Exists(FollowManager_Manager) == false then
Rule_AddInterval(FollowManager_Manager, 1)
end
end
function FollowManager_Manager()
if table.getn(_FollowTable) == 0 then
Rule_RemoveMe()
else
for n = table.getn(_FollowTable), 1, -1 do
local this = _FollowTable[n]
local sourceGroup = this.sgroup2
local targetGroup = this.sgroup1
local distance = this.distance
if SGroup_IsEmpty(sourceGroup) == true
or SGroup_IsEmpty(targetGroup) == true then
table.remove(_FollowTable, n)
return
else
local targetPos = SGroup_GetPosition(targetGroup) -- get the current loc of the target group
local sourcePos = SGroup_GetPosition(sourceGroup)
local compareDistance = Prox_SGroupSGroup(targetGroup, sourceGroup, PROX_SHORTEST)
local longestDistance = distance + 3
local shortestDistance = distance - 3
if compareDistance < distance - 6
or compareDistance > distance + 6 then
local moveToPos = Util_GetOffsetPosition(targetGroup, OFFSET_BACK, distance)
Cmd_Move(sourceGroup, moveToPos)
end
end
end
end
end
function FollowManager_RemoveGroup(sid)
if scartype(sid) == ST_SGROUP then
sid = sid
end
for n = table.getn(_FollowTable), 1, -1 do
local this = _FollowTable[n]
if this.swid == swid then
table.remove(_FollowTable, n)
end
end
if table.getn(_FollowTable) == 0 then
Rule_Remove(FollowManager_Manager)
end
end