Future Syntax - subject to change
Object ids are a feature unique to SkookumScript – they allow game / simulation objects, concepts and assets to be referred to by name in code and have their correctness verified at compile-time – essentially like a dictionary / spelling-checker. This means that typos – including stale names from objects that were renamed or deleted – can be caught before the game is even run and without needing to play through every permutation of game logic to catch invalid names.
Object ids can be used for game characters, trigger regions, sound effects, user interface elements, mission names, cars, cutscenes, props, doors, geographical locations, art assets, game events, AI / behaviour types, animations or anything that you can associate a name to.
Object Ids and Unreal Engine 4
Object ids are currently implemented using
Symbol objects (
ASymbol in C++) and Unreal Engine 4 uses an id system using
Name objects (
FName in C++) which works fairly differently so object-ids are not currently available in the SkookumScript UE4 plugin.
We have since designed a way to have object ids store a
String value in the compiled script binary that can be converted to an engine’s native id type such as
FName as any script binary is loaded. So object ids will be coming to the SkookumScript UE4 plugin in a future update.
Where do Object Id Names Originate?
Unless a class is set to accept any object id name – the names themselves are stored in object id validation files and can come from a world editor, the asset pipeline, the game / simulation itself, hand-written text files, etc.
Of course the names might not be available when the SkookumScript compiler runs – they might be generated by some other tool later in the pipeline. Likewise the valid names may change after SkookumScript has compiled the scripts. No problem. Any object id class type can specify that any id can be initially accepted and then – based on the class meta settings – parsed at a later time. One way to do this is using the SkookumScript IDE simply right click on a class in the class browser and select
Validate 'ClassX' Object Ids or
Validate 'ClassX' + subclass Ids and all the object ids in the classes specified will be checked/rechecked for their correctness without a recompile of any scripts. Just the object ids will be reparsed – any previously complied scripts do not need to be recompiled.
Using Object Ids in Code
Every object id is associated with a SkookumScript class type. If the class type is not specified then the
Actor class is inferred. Each class can maintain its own list of valid object id names.
Object ids have several forms – they either refer to the object that they name or act as a compile-time validated symbol name.
Object Ids Cache References to Objects
If a reference form of an object id is evaluated, it caches the reference of the object (using a memory smart pointer) and will quickly return the same object on successive calls if the object is still valid. It will only look up the object by name again if the previous object goes stale and is removed for some reason.
This means that they can be more speed efficient than a routine call that does a look-up each time it is evaluated.
The reference form of an object id uses an “at” symbol
@. It returns a reference to the named object and will assert if the named object is not present when the object id is evaluated. Its result class type is the same as the class doing the named object lookup. So
Mission@'crazy_space_chase' will have a result class type of
// Actor is inferred @'SomeGuy'.do_stuff // Same as above Actor@'SomeGuy'.do_stuff // Similar to above though in method // form and result not cached Actor.get_named('SomeGuy').do_stuff // Some really common object ids include: @'Player'.do_player_stuff @'World'.set_weather('rain')
@? Potential Reference
The potential reference form of an object id uses an “at” symbol
@ followed by a question mark
?. It returns a reference to the named object or
nil if the object is not present when the object id is evaluated. Its result class type is a union between the object id class and
None (the class type for
Trigger@'trap_door' will have a result class type of
// Actor is inferred so <Actor|None> is result type @?'SomeGuy' // Same as above Actor@?'SomeGuy' // Similar to above though in method // form and result not cached Actor.find_named('SomeGuy') // Generally need to account for possibility of nil !guy: @?'SomeGuy' guy.do_stuff unless guy.nil? // [or] Use apply operator % to ignore call if receiver is nil @?'SomeGuy'%do_stuff
The symbol form of an object id is essentially the same as a symbol literal that is checked at compile-time to ensure that it is valid. It uses an “at” symbol
@ followed by a equals sign
=. It returns a
Symbol. It is useful to use in code that need to reference the name of an object and do not need the object itself.
// Actor is inferred and Symbol is result type @='SomeGuy' // Same as above Actor@='SomeGuy' // Similar to above though as simple symbol // literal that isn't checked by the compiler. 'SomeGuy' // Can be used with methods that need the name of an object my_mission.set_smart_mouth(Robot@='Marvin')
Future: Even Better Than a Dictionary
All the valid name lists and meta data for object ids are available to the SkookumScript IDE so plans are in the works to add auto-complete / drop-down lists for object ids when using the script editor.
Also certain classes of object ids or even a subrange of object ids could be constrained to a specified set of script classes – like only certain mission classes could use mission specific object ids.
Using Object Ids in the C++ Runtime
Object ids require some mechanism to look up objects in the game engine / simulation runtime.
Actor objects have a unique name associated with them, built-in lists that track them and fast look-up calls in C++ to find them. Any object id classes derived from
Actor use these look-up calls by default so making object ids for them is quite easy.
All other classes require a custom object id look-up function to be registered for the object-id to work during runtime – which is pretty easy too. Just register the appropriate calls during SkookumScript initialization in the runtime and type-checked custom names and look-ups are ready to go!