Since V2, Verge has had this concept of separate system codespace and map codespace. While in V1, everything happened in the map code, in V2 and V3, the majority of the important code is now in the realm of the system code, while only events and code relevant to that map is in the map codespace.
Inside either system.vc or system.lua, there should be a void function named
autoexec which takes no arguments (In Lua, that name is case-sensitive). It is called after Verge has finished initializing. That is your entry point into the system code.
In VC, you can
#include any number of additional .vc files from your system.vc in order to provide a logical breakdown of your code components into different source files. For instance, menu.vc, effects.vc, etc. These are all considered to be part of the system codespace. Any functions, variables, or structs you declare in any system file are considered globally accessable.
In Lua, you can use Lua's built-in
require(filename) function to include other files and libraries from a script.
Map scripts are files that are loaded when the active map is switched. They share a common name with the map they are based off, but with an extension of .vc or .lua. For example, if you have a map named test.map, then there must be a test.vc or test.lua. Although the system scripts have one specific entry-point of
autoexec, each map can specify the name of which startup function to run (in Maped3, this is done through the Map Properties dialog). This startup function can exist in the loaded map script or inside system scripts. Similarly, for zone events and entity activation events, these may name a function in either map or system code.
You can access system functions and variables from a map script. In general, most of the descriptions of code you will see in tutorials and discussions on the forum are implicitly describing system code.
Think of a map's code as an extension of system code. In VC, it that only 'exists' while that particular map is loaded, and are added to V3's list of functions when the map is loaded, and unloaded when the map is changed. You can declare as many named functions as you like, functions that return values, helper functions, functions with local variables.
It's important to understand however that, in VC, these functions only exist when that map is loaded. This has the following consequences:
- If you declare a
foo()in system.vc, you cannot declare a
foo()in map1.vc. However, if you have
chest()function in map1.vc, you can also have a
chest()function in map2.vc - provided you don't already have one in system.vc.
- Lets say you have function
Camel()in system.vc, and you have funtions
Hamster()in your map1.vc. From your map code, you can call
Camel()directly. However, because
Llama()only exists when this particular map is loaded, and other maps may have their own functions named
Llama(), it is impossible to know at compile time, which
Llama()to call from a system.vc function. So you cannot directly call
Llama()from a system function. What you can do is use
CallFunction("Llama"), which will call the function if it exists at that time, or simply return and do nothing if that function does not exist at runtime. While you cannot call a map vc function directly from a system vc function, you can call another map function directly from another function in that same map file. In the above example, you could call
Hamster()directly without needing to use
CallFunction, because it is known at compile time exactly which function you're talking about.
- Because of this concept that the functions declared in a map VC only exist while that map was loaded - in addition to certain technical considerations - it was decided that you cannot declare global variables in a map VC file. You can declare local variables in your map VC functions, and you can use global variables declared in system.vc. But you cannot declare global variables in a map VC file, because they would cease to exist when the map was unloaded. While we intuitively think of a local variable as being non-persistent between function calls, we DO think of global variables as being persistent, so having your global variables pop out of existence would be confusing and prone to bugs.
In Lua, the rules are a bit different. System and map scripts share the same global namespace, so a global assigned in a map script will replace the previous global entries, even if the map is unloaded. You can define map variables, or map functions (which are a kind of variable with a function value) as you wish. This has the side-effect of potentially overwriting system globals and also having globals persist after a map change. Likewise system code can overwrite map-related variables and functions (because again, they are the same global namespace). This may undesirable, but careful naming schemes and use of the
local keyword whenever possible will help reduce this problem.