Messages logged to the DEBUG channel are visible in the CET console by default (without having to enable game logs).
LogChannel(n"DEBUG", "something")
General purpose hash map
There are several hash map implementations available in the game. Most importantly, inkHashMap (Uint64 -> ref<IScriptable>) and inkWeakHashMap (Uint64 -> wref<IScriptable>). All custom classes extend IScriptable therefore they can be used as values in those hash maps.
let map = new inkHashMap();hashMap.Insert(TDBID.ToNumber(t"key1"), MyClass.Create(1));hashMap.Insert(TDBID.ToNumber(t"key2"), MyClass.Create(2));let value: ref<MyClass>= map.Get(TDBID.ToNumber(t"key1"))as MyClass;
Safe downcasting
The as operator returns null when a dynamic cast fails. You can use it combined with IsDefined to perform safe downcasts.
let manager = employee as Manager;ifIsDefined(manager) {// employee is known to be Manager here}
Heterogeneous array literals
If you define a function to accept an array of Variant:
funcAcceptVariants(variants: array<Variant>) {}
Then that function can be called with an array literal containing elements of different types:
// all elements get implicitly converted to VariantAcceptVariants([1, new Vector2(1, 2), new inkText()]);// you can achieve the same thing with an explicitly typed locallet variants: array<Variant>= [1, new Vector2(1, 2), new inkText()];
This scriptable system can then be accessed using the scriptable system container:
let container = GameInstance.GetScriptableSystemsContainer(gameInstance);// don't forget the namespace if you're using moduleslet system = container.Get(n"MyMod.MySystem")as MySystem;LogChannel(n"DEBUG", ToString(system.GetData()));
Persisting data
The fields of classes that extend ScriptableSystem or PersistentState (e.g. ScriptedPuppetPS) can be declared with the persistent modifier to be persisted in game saves.
You can persist data of all types except for String, Variant and ResRef (and arrays of these types).
Instances of classes can be persisted too, but note that their fields must also be marked as persistent, or they won't be persisted and instead they'll be initialized with defaults.
module MyModpublicclassEntry {// both of these will be persistedpublic persistent let related: TweakDBID;public persistent let lasting: Int32;// this won't be persistedpubliclet temporary: Int32;}publicclassMySystem extends ScriptableSystem {private persistent let m_entries: array<ref<Entry>>;}
Constructing Class Object
Redscript does not have Class constructors and to set the data of class fields you would have to either do that manually
publicclassCustomClass{//all the variables publiclet myInt: Int32;publiclet myString: String;}
let myCustomClass = new CustomClass();myCustomClass.myInt =1;myCustomClass.myString ="Hello";
or if you want to do it with a single clean line
publicclassCustomClass{//all the variables publiclet myInt: Int32;publiclet myString: String;publicstaticfuncCreate(inputInt: Int32, inputString: String) -> ref<CustomClass>{//you create the new instance of your class here instead of in your code//and set its variableslet self = new CustomClass(); self.myInt = inputInt; self.myString = inputString;return self; }}
and how to use it
let myCustomClass = CustomClass.Create(1,"Hello");
DelaySystem and DelayCallback
DelaySystem is a class that allows async call of DelayCallback after the set amount of time has passed.
this is how to create a DelayCallback
publicclassCustomCallback extends DelayCallback{//all the data that your Call function needsprivatelet myInt: Int32;publicfuncCall() {//custom function that i want to be called when the specified time has passedif this.myInt>1 {LogChannel(n"DEBUG", "Input is bigger than 1"); }else {LogChannel(n"DEBUG", "Input is smaller than 1"); } }publicstaticfuncCreate(inputInt: Int32) -> ref<CustomCallback> {//use this way to create your Callback class in one linelet self = new CustomCallback(); self.myInt = inputInt;return self; }}
and this is how you can use the DelaySystem to call the Callback function with a delay