Hi everyone,
I am here to share with you our scripting system, AutumnScript, which is an interpreted language developed for Unity3d. AutumnScript includes an interpreter to parse and evaluate scripts at runtime. It is written in C# so it is compatible with Unity3d on both Android and iOS. We are currently using this in our own RTS/4x games so it is currently being developed actively.
Download it here: (same as the link below)
https://drive.google.com/drive/folders/0B48mY36DgTsnM01BeXpVcmdOZnc?usp=sharing
Features:
- Scripts are loaded and interpreted by the system in realtime.
- Script syntax are closely resembled JavaScript.
- Written in C#, work with Unity out of the box.
- Easy to setup in Unity. (just drop the dll in)
- Scripts are embeddable in most external serialized data format (json, xml, etc.)
- Options to run on the main game thread or on its own separate thread (more preferred)
- Complete sandbox: AutumnScript cannot access/modify its host’s memory without the host explicitly setup bindings before.
- Host can provide functions (in C#) and bindings (bind a C# variable to its AutumnScript variable)
- Host can inspect/modify Autumn Script memory
- (Hopyfully/Trying to) use minimal garbage
- Work on multiplatform: PC, Android, iOS
Yeah I know Lua is the mainstream choice out there. I would have to admit Lua probably still be a better choice in large projects because:
- Performance: there is a reason the saying “as fast as Lua” exist. AutumnScript runs on top of C# (which is already slow), so it will never be able to compete with Lua on this.
- Debugging: there are only 2 ways to debug an AutumnScript program: via console print and via memory inspections. There are no breakpoints system whatsoever

- Documentation: AutumnScript’s is non existence (for now)
Currently we are using AutumnScript in multiple ways in our projects. Here are some of the use cases that I find interesting:
- Embedded script in jsons:
You can write your scripts inside the bracket </ … /> and embedded within your own json*.* When the interpreter picks up the json and decide to evaluate, all scripts would then be executed in the reading order (left to right, top to bottom) and the return values would then be replaced to the json. At the end of the day, we can have a “morphable” json that is useful for generating dynamic conversations and game rules.
Example:
{
"Name" : "Cultivate Lands",
"Description" : "Increases Agriculture by </base = 17 - _agriculture / 15; return round (1.35 * base - 5)/> to </return round (2.35 * base - 5)/>",
"FlavorDescription" : "Increase harvest by having men work on the fields.",
"MissionCondition" : "</return _marketplace && _population > 5000/>",
"DominantStat" : "int",
"Duration" : "28",
"CostFoodMax" : "0",
"CostFoodMin" : "0",
"CostGoldMax" : "0",
"CostGoldMin" : "200",
"Recommendation" : "</responses = ['It may be wise to send someone else for this task...', 'I do not know much about agriculture, but I will do my best.', 'We will be able to harvest greater yields from our crops!', 'I will have my men oversee the fields.']; i = int < 0.5 * int_average ? 0 : int < 0.8 * int_average ? 1 : int < 1.2 * int_average ? 2 : 3; return responses[i];/>",
"ConfirmMessage" : "Assign </return target_officer/> to cultivate the lands of </return current_province/>?",
"Failure" : "</_agriculture += roundup (50 / _agriculture) * 15 + (rand (20) + 4) * int / 100)/>We have succesfully improved irrigations, and we can look forward to a better harvest next month.",
"Success" : "</base = 17 - _agriculture / 15; _agriculture += round ((0.1 + rand (6) / 10 + (int + 50) / 200 + 1) * base - 5);/>We have succesfully improved irrigations, and we can look forward to a better harvest next month.",
"SuccessCondition" : "</return int + 60 > rand(100)/>"
}
- Game “patching”:
With the variable bindings feature, designers can write scripts that are executed on start up to modify/monkey patch certain parameters in the engine, hence can easily mod the system. An example of this would be:
// Patch code for mission 1
hsu = mission.findUnit ("Scholar Hsu");
hsu.movementSpeed -= 200; // Should not be able to out run the bandits
hsu.visionRange -= 150;
- Provide event functions:
With the ability to declare functions, designers can write their own modified logic whenever an pre-specified event happens:
battleCries = [
"Down with the Empire!",
"Charge!",
"Attack!",
"Arggghhh!!!" // 3!!
];
onUnitComeIntoVision = function (unit) {
if (currentPlayer.isEnemy (unit) && unit.name == "Bandit") {
battleCry = battleCries[rand (4)];
unit.spawnSpeechBubble (battleCry);
}
}
mission.addEventListener ("unitComeIntoVision", onUnitComeIntoVision);
You can download the library (as .dll), as well as the simple script editor below (both on PC and Android) and try out the system:
(same as the link above)
https://drive.google.com/drive/folders/0B48mY36DgTsnM01BeXpVcmdOZnc?usp=sharing
The Unity project repo:
https://github.com/ngtrhieu/autumn_script_unity
For this particular build, there are only a few built-in functions:
- print (var): print the variable to the on screen console.
- error (var): print the variable in red to the on screen console.
- loadScript (scriptName): load the saved script and replace it in the editor. (some default scripts: ‘hello’, ‘factorial’. ‘prime’ and ‘setScriptColor’)
- saveScript (scriptName): save the current script under the scriptName. You can load your script later using ‘loadScript’
- Array.length (arr): return the length of the array
- Array.push (arr, var): add the variable to the end of the array
- Array.pop (arr): remove the last element of the array and return it
- Array.removeAt (arr, index): remove the element at specific index of the array
The only binding variable:
- textEditorColor: bind to the C# variable which control the color of the text in the editor
You can try out a few examples by running loadScript (‘hello’), loadScript (‘factorial’), loadScript (‘prime’), loadScript (‘setScriptColor’) to get the sense of the syntax used in AutumnScript before trying to write your own program. (please run them one by one)
Currently I would like to push the system further and would like to know your opinions on:
- Do you think the system is user friendly?
- Is there missing features you want to have?
- Do you think it is helpful to your games? (Please tell me a little bit about your games too)
- How/Which direction should I improve this further?
Please try out and let me know your thoughts. Your comment on the subject is really appreciated.
Cheers,