This are original documentations from here.
If you found other scripting documentations, you can post here.
Resource definition file (__resource.lua)
This document lists valid directives provided by the core and other resources for the resource definition file (__resource.lua).
Directives (general info)
A directive is basically a Lua function invoked by the ‘identifier followed by string or table equals a call’ rule - unknown directives are handled by returning a dummy function instead of nil (this means any undefined variable is actually a function - keep this in mind!). In effect, the following are equal:
client_script 'a.lua' # implicit call
client_script('a.lua') # explicit call
client_scripts
Lists one or multiple client scripts for the resource. Parsed by both client (to load scripts) and server (to offer scripts for download). Aliased as client_script.
client_script 'client.lua'
client_scripts {
'client1.lua',
'client2.lua'
}
dependencies
Lists one or multiple required resources for this resource. Aliased as dependency.
dependency 'chat'
dependencies {
'dot',
'test'
}
description
Sets the meta field ‘description’ in the resource’s metadata.
description 'My resource'
exports
Lists one or multiple client-side script exports for other resources to call - these are taken from the resource’s global environment. Aliased as export.
export 'getStuff'
exports {
'getStuff',
'getOtherStuff'
}
server_scripts
Lists one or multiple server scripts for the resource. Only parsed server-side. Aliased as server_script.
server_script 'server.lua'
server_scripts {
'server1.lua'
'server2.lua'
}
version
Sets the meta field ‘version’ in the resource’s metadata.
version '1.0'
Calling an export
An export can be called from any resource on the client (tbi on the server) as follows:
exports.myresource:getStuff(1, 2, 3)
Your first resource - a basic car spawner
Let’s start demonstrating the interaction between client and server resources and events by making a simple resource that will spawn a car when a message in the chat equals ‘car’.
As stated in the previous page, creating a resource requires you to make a subfolder, and a __resource.lua file. Therefore, we will make a folder called mycar in our resources/ folder, and create a new file called __resource.lua in the same directory.
A:\citizen-data\resources> mkdir mycar
A:\citizen-data\resources> cd mycar
A:\citizen-data\resources\mycar> notepad __resource.lua
The content in this file will be simple - we’re just creating a single client script and a single server script:
description 'my cute car spawner'
client_script 'client.lua'
server_script 'server.lua'
As chat messages are primarily handled on the server (as shown in the event documentation – you’ll be referring to it often!), we’ll start with the server script. It is as follows:
AddEventHandler('chatMessage', function(from, name, message)
if message == 'car' then
TriggerClientEvent('mycar:createCar', from, 'turismo')
end
end)
The server’s primary means of code execution is through events like these - the client also has the ability to create threads, which execute in the background together with the game.
As shown in the documentation for chatMessage], the first argument is the client ID of the player who sent the chat message. The ‘mycar:createCar’ event is our custom one, which we’ll implement below.
Going from there, we’re going to be creating the client script. We’ll show a basic example of the base framework, explain it, then continue on adding vehicle spawning.
AddEventHandler('mycar:createCar', function(model)
-- ...
end)
Again, this is another event handler as above.
Now, to actually spawn a vehicle, some knowledge of single player GTA scripting is fairly helpful. There are various guides available both for the GTA III series which partially apply here, and somewhat less guides for IV. Basically, to create a local entity, one starts by loading a model. This could be done like this, kind of:
local hash = GetHashKey(model, _r)
RequestModel(hash)
LoadAllObjectsNow()
This shows the way we interact with the game fairly clearly, as well - these functions are the so-called ‘native functions’ from the game, and are listed on various sites. These functions may return various return value types, such as ‘results’ and have ‘pointer arguments’. The _r in this example stands for ‘return result as integer’, and a full list follows:
Variable | Effect |
---|---|
none | return result, with 0 being converted to a boolean |
_r | return result as integer, without boolean conversion |
_b | return result as a boolean, even if a pointer argument is returned |
_rf | return result as a floating-point value |
_s | return result as a string |
_i | return pointer as integer |
_f | return pointer as floating-point value |
If multiple reference items are specified, the return values will occur from left to right, like the following:
local x, y, z = GetCharCoordinates(ped, _f, _f, _f)
However, there’s some issue with this model loading code, which has to be resolved in a better way: as loading a model may take a while, and the player is, well, playing the game, it’s usually a good idea to load the model asynchronously. This is typically done in native script by invoking a ‘wait’ command/function in a loop - and it’s no different here…
… except you need a thread for this. Threads in CitizenMP are simply Lua ‘coroutines’, and therefore if you’re used to threads being a ‘bad thing’, they’re typically not over here. Let’s show how to actually do this:
-- hash and such
CreateThread(function()
RequestModel(hash)
while not HasModelLoaded(hash) do
Wait(0)
end
-- do stuff with your model
MarkModelAsNoLongerNeeded(hash)
end)
This also introduces another new concept - marking models as ‘no longer needed’. If one is not going to perform further script operations on any game resource (whether it be an entity or model), it’s recommended to mark them as unneeded - this allows the game to release the memory resources required for this resource (that’s a lot of resource when it’s able to.
Now that we have the model loaded, we can actually continue by creating our car. This usually ends up being done as follows:
local ped = GetPlayerPed()
local x, y, z = GetCharCoordinates(ped, _f, _f, _f)
local car = CreateCar(hash, x + 1, y, z, _i, 1)
WarpCharIntoCar(ped, car)
-- this doesn't work in current CitizenMP, sadly - it's kind of needed to allow cars to despawn safely
-- MarkCarAsNoLongerNeeded(car)
Note that GetPlayerPed isn’t a native function, but a convenience function we made to simplify getting the player’s character.
If we put it all together, as shown below…
AddEventHandler('mycar:createCar', function(model)
local hash = GetHashKey(model, _r)
CreateThread(function()
RequestModel(hash)
while not HasModelLoaded(hash) do
Wait(0)
end
local ped = GetPlayerPed()
local x, y, z = GetCharCoordinates(ped, _f, _f, _f)
local car = CreateCar(hash, x + 1, y, z, _i, 1)
WarpCharIntoCar(ped, car)
MarkModelAsNoLongerNeeded(hash)
end)
end)
… we have our complete client script!
Let’s try it out: add a line to your server .yml file’s AutoStartResources section to list ‘mycar’, start the server, join, and type ‘car’ in the chat. If everything’s okay, you should be put in a Turismo just fine! If not…
Streaming/CdImage files
CitizenMP:IV has the ability to override/insert files that would normally be placed in ‘CD images’ (.img files) at runtime. This, however, is bound to a few specific limitations:
- No API. These files are simply loaded from a folder, without any exclusions specifiable.
- Only at initialization. Streaming overrides only get initialized during game initialization, which basically means ‘during connecting to the server’. Dynamic resource starting/stopping won’t allow overriding these in the current version, and may not do so for a while to come.
Usage
To use this feature, simply create a folder titled stream in a resource folder (one that is started by AutoStartResources, preferably) and place streaming files (.wft, .wtd, .nod, .sco, …) in there. These will only be downloaded on demand (i.e. when said streaming object is requested, for instance by a call to RequestModel) and will be cached on the client locally for future usage.
The folder’s content can be categorized in subfolders for organization, these have no meaning to the game whatsoever.
Events
chatMessage
Definition
Client
AddEventHandler('chatMessage', function(name, color, message) end)
Server
AddEventHandler('chatMessage', function(from, name, message) end)
Arguments
- from: The network ID of the client sending the chat message.
- name: The name of the player sending the chat message.
- color: A table containing a RGB color the chat message should be displayed as.
- message: The actual chat message.
This event can be canceled.