UScript for Unturned Quick Tips

From Free Knowledge Base- The DUCK Project
Jump to navigation Jump to search

resolving errors

object reference not set to an instance of an object

One or more objects used in the script are at some point null during runtime.

For example, take the line of code

if (player.id == strName) {

Rewrite it as

uScript syntax is case sensitive

As an example, the property .length is all lower case, whereas in C# it is more common to see .Length as a property.

If we have an array called vPlayer, and thus the property is player.length which is a property of the array object. In object-oriented programming, a property is a value associated with an object that can be accessed or modified.

understanding functions

When you call a function the function returns a value as the name of the function.

fnPlayerOnline(strPlayer.id)

Will return true or false if the function is written to do so. strPlayer.id is passed to the function from the calling line of code. Such as

if (fnPlayerOnline) { do something if player is online; }

values passed to the function are not returned to the calling part of the program, or available outside of the function.

if (isFruit(food1, food2, food3) {

The function "isFruit" will receive the values of food1, food2, and food3. If those values are modified within the function, those modified values will NOT be returned. uScript has no support for "ref" or "out" and the only way that the function can modify the values and have them available outside of the function is to declare them as global, or make the function itself an array.

understanding code

properties vs. methods and how object data is managed in uScript/C#

An object might expose its data as properties. An object may be private or read-only field—meaning it cannot be set directly. For example if I have the object "str.owner" which gets its value from server.getStructuresInRadius filling it like an array, it can not be assigned directly. Take the code example:

foreach(str in server.getStructuresInRadius(player.position, 50)){ str.set_owner(pid); }

You can see str is gathering more information than just on one thing, but on several things "structures" that are within a radius. For each one, we want to set a new value of "owner" but we can not use Direct Property Assignment (str.owner = pid;) because it will generate the error

error: Info: structure.set_owner: invalid argument(s) for function - set_owner(string)

Therefore we assign the value using a Setter Method

str.set_owner(pid);

The presence of set_owner(string) suggests that owner is controlled via a method. uScript wants you to use an official function to change ownership rather than allowing direct modification. Many game engines restrict direct property modification for important in-game objects to prevent unintended behavior or security issues. By forcing the use of set_owner(string), Unturned ensures that ownership changes go through controlled logic.

  • Direct assignment (=) works only if the property is publicly writable.
  • Method calls (set_owner()) enforce rules and logic that the game developers want.

This pattern is common in API design where direct field manipulation is restricted to maintain stability and prevent exploits.

If a property isn’t writable directly, look for a method (set_owner, update_owner, etc.). If you can’t find one, try assigning directly. Check for Getters (get_ Prefix), meaning that if str.owner exists but is read-only, the game might have a corresponding str.get_owner() method to retrieve the value instead.

command permissions

command meant for players you do not want ran from console

This is what the "allowedCaller" designation is for.

command command() {
    allowedCaller = "player";   
    execute() {

    }
}

SQL tips

SQL execution methods in uScript for Unturned:

database.firstRow

Retrieves the first row of the result set. Appropriate for queries that return a single result, such as fetching a specific player's data. Example use case:

local row = database.firstRow("SELECT * FROM players WHERE id = ?", playerID)

database.nonQuery

Executes an SQL statement that does not return a result set. Used for INSERT, UPDATE, or DELETE statements. Example use case:

database.nonQuery("UPDATE players SET balance = ? WHERE id = ?", newBalance, playerID)

database.allRows

Retrieves all rows of the result set. Used when multiple records are expected, such as listing all online players. Example use case:

local rows = database.allRows("SELECT * FROM players WHERE balance > ?", minBalance)

database.execute

Runs an SQL command but does not return results. Typically used for schema modifications (CREATE TABLE, DROP TABLE, ALTER TABLE). Example use case:

database.execute("CREATE TABLE IF NOT EXISTS players (id INTEGER PRIMARY KEY, name TEXT, balance INTEGER)")

Each method should be used based on whether you need to read, modify, or structure the database.

related