Actions

Script3 Things: Difference between revisions

From Populous Wiki

(Placeholder)
 
No edit summary
Line 1: Line 1:
Placeholder
== Introduction To Things ==
In Script 3 there is many way you may come across an object named 'Thing' which is just the name of all objects on the game such as huts, braves, spells, etc. Depending on how you come across these objects determines what you must do before you can use them. If you improperly use an object the script engine is not going to tell you; the game will just crash. Any long term storage of a Thing in your scripts should be stored in an ObjectProxy and checked for null each access. This is because if you store a raw Thing the Thing might be deleted/destroyed on the next turn and the Thing WILL NOT be null. In fact it may not even be the same Thing anymore. For example lets say you stored a shaman in a global Thing and the shaman dies on the next turn and that Thing is reused for a hut. The script may think that hut is a shaman and crash.
 
If you call any of the ProcessList functions, every one of the calls to your function you specified to ProcessList is guaranteed to exist within the scope of your defined function. However, the return value of ProcessList MUST be checked for null if you are using the return value.
 
=== Table of Functions and null check requirement. ===
{| class="wikitable sortable"
|-
! Function !! Check For Null !! Notes
|-
| ProcessGlobalTypeList|| Partial || Only On Return
|-
| ProcessGlobalUsedList|| Partial || Only On Return
|-
| ProcessGlobalSpecialListAll|| Partial || Only On Return
|-
| ProcessGlobalSpecialList || Partial || Only On Return
|-
| createThing || Always ||
|-
| FindNextGlobalTypeList || Always ||
|-
| FindNextGlobalUsedList || Always ||
|-
| FindNextSpecialList || Always ||
|-
| findWood || Always ||
|-
| ObjectProxy || Always ||
|-
| GetThing || Always ||
|}
 
=== Example 1 ===
 
For example the this function listAllThingNums should always give a Thing that exists and does not need to be checked if it is null. However the return value of ProcessGlobalUsedList is not guaranteed to exist so that needs to be checked for null. Remember ProcessGlobalUsedList returns the last object processed on a return false, else it returns null.
# def giveMeFirstThingNum(Thing)
# {
#    log(Thing.ThingNum);
# return false;
# }
# var retT = ProcessGlobalUsedList(giveMeFirstThingNum);
#
# if (retT.is_var_null())
# {
#    log(retT.ThingNum);
# }
 
=== Bad Code Vs. Good Code ===
 
Bad Code:
# global shaman = getShaman(TRIBE_BLUE);
#
# def OnTurn()
# {
#    log(shaman.ThingNum);
# }
Reason: Shaman may not exist on the next turn and will not become null.
 
Correct Code:
# global shaman = ObjectProxy(getShaman(TRIBE_BLUE));
#
# def OnTurn()
# {
#    if (!shaman.isNull())
#    {
#        log(shaman.ThingNum);
#    }
#    else
#    {
#        log("Shaman has died");
#    }
# }
 
Bad Code:
# global shaman = ObjectProxy(getShaman(TRIBE_BLUE));
#
# def OnTurn()
# {
#    log(shaman.ThingNum);
# }
Reason: Once the shaman object dies shaman will become null, thus it is required to check if it is null before accessing else the game will crash.
 
Good code:
# global shaman = ObjectProxy(getShaman(TRIBE_BLUE));
#
# def OnTurn()
# {
#    if (!shaman.isNull())
#    {
#        log(shaman.ThingNum);
#    }
# }
#

Revision as of 01:31, 16 April 2019

Introduction To Things

In Script 3 there is many way you may come across an object named 'Thing' which is just the name of all objects on the game such as huts, braves, spells, etc. Depending on how you come across these objects determines what you must do before you can use them. If you improperly use an object the script engine is not going to tell you; the game will just crash. Any long term storage of a Thing in your scripts should be stored in an ObjectProxy and checked for null each access. This is because if you store a raw Thing the Thing might be deleted/destroyed on the next turn and the Thing WILL NOT be null. In fact it may not even be the same Thing anymore. For example lets say you stored a shaman in a global Thing and the shaman dies on the next turn and that Thing is reused for a hut. The script may think that hut is a shaman and crash.

If you call any of the ProcessList functions, every one of the calls to your function you specified to ProcessList is guaranteed to exist within the scope of your defined function. However, the return value of ProcessList MUST be checked for null if you are using the return value.

Table of Functions and null check requirement.

Function Check For Null Notes
ProcessGlobalTypeList Partial Only On Return
ProcessGlobalUsedList Partial Only On Return
ProcessGlobalSpecialListAll Partial Only On Return
ProcessGlobalSpecialList Partial Only On Return
createThing Always
FindNextGlobalTypeList Always
FindNextGlobalUsedList Always
FindNextSpecialList Always
findWood Always
ObjectProxy Always
GetThing Always

Example 1

For example the this function listAllThingNums should always give a Thing that exists and does not need to be checked if it is null. However the return value of ProcessGlobalUsedList is not guaranteed to exist so that needs to be checked for null. Remember ProcessGlobalUsedList returns the last object processed on a return false, else it returns null.

  1. def giveMeFirstThingNum(Thing)
  2. {
  3. log(Thing.ThingNum);
  4. return false;
  5. }
  6. var retT = ProcessGlobalUsedList(giveMeFirstThingNum);
  7. if (retT.is_var_null())
  8. {
  9. log(retT.ThingNum);
  10. }

Bad Code Vs. Good Code

Bad Code:

  1. global shaman = getShaman(TRIBE_BLUE);
  2. def OnTurn()
  3. {
  4. log(shaman.ThingNum);
  5. }

Reason: Shaman may not exist on the next turn and will not become null.

Correct Code:

  1. global shaman = ObjectProxy(getShaman(TRIBE_BLUE));
  2. def OnTurn()
  3. {
  4. if (!shaman.isNull())
  5. {
  6. log(shaman.ThingNum);
  7. }
  8. else
  9. {
  10. log("Shaman has died");
  11. }
  12. }

Bad Code:

  1. global shaman = ObjectProxy(getShaman(TRIBE_BLUE));
  2. def OnTurn()
  3. {
  4. log(shaman.ThingNum);
  5. }

Reason: Once the shaman object dies shaman will become null, thus it is required to check if it is null before accessing else the game will crash.

Good code:

  1. global shaman = ObjectProxy(getShaman(TRIBE_BLUE));
  2. def OnTurn()
  3. {
  4. if (!shaman.isNull())
  5. {
  6. log(shaman.ThingNum);
  7. }
  8. }