# Ublockly guide All credit for the implementation of the ublocky library goes to [imagicbell](https://github.com/imagicbell). We are merely expanding on this library as is permitted under the [Apache License 2.0](https://github.com/imagicbell/ublockly/blob/master/LICENSE). Reimplementation of google blockly for Unity done by [imagicbell](https://github.com/imagicbell) https://github.com/imagicbell/ublockly Two basic game demos for ublockly. https://github.com/imagicbell/ublocklygame ## How to change language To add a new language you should do the following steps: 1. Go to `UBlockly/UserData/I18n` and add a translated file for the new language. 2. On `UBlockly/UserData/Resources/BlockResSettings` change the `Size` variable to the number of languages you want to support and add an `Index Name`, a `Res Name` and the `Text File` for the new language. (Fig. 1) 3. On `UBlockly/Source/Script/Core` open the file `Blockly.cs` and on line 35 replace `PT` with the Index of the new file you just added. (Fig. 2) <br> <div align="center"><img height="350" src="https://i.imgur.com/i2T38Tx.png" /></div> <div align="center">Fig. 1</div> <br> <br> <div align="center"><img height="200" src="https://i.imgur.com/zq4RSmr.png" /></div> <div align="center">Fig. 2</div> <br> ## How to create categories/blocks Each block has a specific category associated with it, for example, the block named "basic_start" is a block that belongs to the basic category and its name is start. Each category needs to have a specific json file where all its blocks are defined. To add a block to an a existing category, just add the json definition block the corresponding json files. The basic categories that came with ublockly were: * colour * list * coroutine * logic * loops * procedures * math * text * variables The categories list, text and colour were eliminated because they were not necessary to the project. ### Create a new category 1. **Create a Json category file** To create a new category first it is necessary to create a new json file for it, although you can create that file anywhere in the project we suggest that for consistency reasons it is created under `Assets/UBlockly/Source/JsonBlocks`. The name of the json file should be the name of the category to be create. <br> <div align="center"><img height="250" src="https://i.imgur.com/g25HvmZ.png" /></div> <div align="center">Fig. Json files for the categories</div> <br> 2. **Add category reference to settings file** After creating the json file it is necessary to add its reference to the attribute BlockJsonFiles in the BlockResSettings file under `Assets/UBlockly/UserData/Resources`. This file contains major configuration settings for all the ublockly library. <br> <div align="center"><img src="https://i.imgur.com/EIWAimg.gif" /></div> <div align="center">Fig. Adding a new category to settings file</div> <br> 3. **Add category to toolbox_config file** With the json referenced on the settings file it is still necessary to make the category appear on the interface. To show the newly added category it is necessary to add it to the toolbox config file named toolbox_default at `Assets/UBlockly/UserData/Toolboxs/Configs`. <br> <div align="center"><img src="https://i.imgur.com/XAtT2ye.gif" /></div> <div align="center">Fig. Changing the toolbox file</div> <br> 4. **Add category language translation to language file** After all this, the final step in creating a new category is to add a translation for the new category name in the language file at `Assets/UBlockly/UserData/I18n` (pt.json is the default language file). <br> <div align="center"><img src="https://i.imgur.com/hj1KX17.gif" /></div> <div align="center">Fig. Changing the language file</div> <br> ### Create a new block To create a new block, add its json definition to one of the category json files. The definition of a block follows a strict format. Block Definition Format: ``` "type": "[CategoryName]_[BlockName]", "message0": [Message], "args0":[ { "type": [Type] "name": [Name] "message": [ArgMessage] "check": [Check] "variable": [Variable] "options": [Options] }, ... ], "message1": [Message] "args1":[ { "type": [Type] "name": [Name] "message": [ArgMessage] "check": [Check] "variable": [Variable] "align": [Align] "options": [Options] }, ... ] .... "messageN: [Message], "argsN": [ ... ], "previousStatement": [PreviousStament], "nextStatement": [NextStatement], "output": [Output], "inputsInline": [InputsInline], "mutator" : [Mutator], "extensions": [Extensions], ```` **The only json parameters that are required is the type, at least one message and the args of that message, the rest are all optional**. ```[CategoryName] : string``` Name of the category, should be the same as the name of the file, example: "variable" and "basic". ```[BlockName] : string``` Name of the block that should be representative of the block's desired functionality. ```[Message]``` Message represents the final message that will be show to the block, it will be something like this "%{BKY_CONTROLS_IF_MSG_THEN} %1 %2" where {BKY_CONTROLS_IF_MSG_THEN} is a constant that will be retrieved from the language file and %1 %2 are the arguments that will be defined in the args array. ```[Type]: string``` The type of the field, possible values: * "field_label" ![](https://i.imgur.com/NyOcVwm.png) * "field_angle" ![](https://i.imgur.com/IsG03uh.gif) * "field_checkbox" ![](https://i.imgur.com/T591oI8.png) * "field_dropdown" ![](https://i.imgur.com/6imnEpN.png) * "field_input" ![](https://i.imgur.com/WBbtWse.png) * "field_number" ![](https://i.imgur.com/kZN17ii.png) * "field_variable" ![](https://i.imgur.com/XGWmSJS.gif) * "input_value" ![](https://i.imgur.com/ATw4fja.gif) * "input_statement" ![](https://i.imgur.com/Zp4p0VA.png) * "input_dummy" ![](https://i.imgur.com/Xzo004i.png) ```[Name] : string``` Name of the argument ```[ArgMessage] : string ``` Is the message that is going to be displayed for that argument ```[Check] : string``` If the type is "input_value" then it represents the type of value that block must return ("Boolean", "Number", "String", "List", "Undefined") ```[Variable] : string``` If the type is "field_variable" then it represents variable selected ```[Align] : string``` The alignment of the message relative to the block, possible values: * "RIGHT" ![](https://i.imgur.com/mBZY24R.png) * "CENTER" * "LEFT" ```[Options] : array``` if the type of the message is field_dropdown then the it is possible to declare an array with the options for the dropdown, just like this ![](https://i.imgur.com/nHKETvA.gif) ```[previousStatement] : null ``` If this parameter is present then the block will be able to connect to other blocks at the top, just like this ![](https://i.imgur.com/R84huwI.png) ```[nextStatement] : null``` If this parameter is present then the block will be able to connect to other blocks at the bottom, just like this ![](https://i.imgur.com/C6GRry4.png) ```[inputsInline] : boolean``` ```[extensions] : array``` ```[mutator] : string``` **A Block cannot have both "output" and "previousStatement" json parameters.** Example of the block definition for the block "variables_set": ```{ "type": "variables_set", "message0": "%{BKY_VARIABLES_SET}", "args0": [ { "type": "field_variable", "name": "VAR" }, { "type": "input_value", "name": "VALUE" } ], "previousStatement": null, "nextStatement": null, "extensions": ["contextMenu_variableSetterGetter"] } ``` If the block definition doesn't follow the previous described format then an exception will be thrown. ## How to add functionality to a block To add functionality to a block it is necessary to add the code that must be executed when that certain block is present, to do this we need an interpreter. **[NOTE]** Currently there are no plans on showing the user the code he programmed with blocks so there's no need to create generators, that's why the Generators section is marked as **optional**. ### Interpreters Interpreters, in the ublockly library, are used to directly execute instructions that were created when the user programs the rocket with blocks. Currently, ublockly only has interpreters for C# since this is the default language used by unity. The available interpreters can be found at `Assets/UBlockly/Source/Script/CodeDB/CSharp/Interpreters`. There is one interpreter per category of blocs. If a new category is created then a new interpreter C# script must be created with the following format `[CategoryName]_[ProgrammingLanguage]`; <br> <div align="center"><img src="https://i.imgur.com/iBUGwQM.png" /></div> <div align="center">Fig. Interpreters folder</div> <br> The interpreter C# script follows the next general format: ``` namespace UBlockly { // This next block of code is for one block, if the //category has multiple blocks repeat this for each one [CodeInterpreter(BlockType = [BlockCategoryName])] public class [CategoryName]_[BlockName]_Cmdtor : EnumeratorCmdtor { protected override IEnumerator Execute(Block block) { [Execute some code] } } } ``` `[BlockCategoryName]` is the name of the block in the block json definition, example: "basic_start" or "variables_get". `[CategoryName]` is the category of the block, example: "Basic" or "Variable". `[BlockName]` is the name of the block, example: "Start" or "Get" `[Execute some code]` is supposed to represent the code that must run in case that block is present. ### Generators (OPTIONAL) Generators, in the ublockly library, are used to generate code based on the blocks used. This is useful to show the user the code he made with blocks in a certain programming language. Currently, ublocky has generators for 2 languages C# and Lua. The available generators can be found at `Assets/UBlockly/Source/Script/CodeDB/CSharp/Generators`, `Assets/UBlockly/Source/Script/CodeDB/Lua/Generators`. There exists one generator per category of blocs per language (C# and Lua). If a new category is created then a new generator script must be created with the following format `[CategoryName]_[ProgrammingLanguage]` <br> <div align="center"><img src="https://i.imgur.com/RjOuO06.png" /></div> <div align="center">Fig. Generators folder</div> <br> The generator C# follows the next general format: ``` namespace UBlockly { // This next block of code is for one block, if the //category has multiple blocks repeat this for each one [CodeGenerator(BlockType = [BlockCategoryName])] private string [BlockFunctionName](Block block) { return "[Code]" } } ``` `[BlockCategoryName]` is the name of the block in the block json definition, example: "basic_start" or "variables_get". `[BlockFunctionName]` is the name of the function, no convention here but should be representative of the block's name and category. `[Code]` is the code that in C# that represents the block . ## How to configure the Settings files There are two Settings under `Assets/Ublockly/UserData/Resources`. * BlockResSettings * Load Type Define which way to load resources. Default Serialized. * I18n Files Add a reference to a language file. Remember to check the selected checkbox. * Block Json Files Add customized block json files. * Toolbox Files Add a customized toolbox config files. e.g. change colors of blocks, select block categories, etc. Remember to check the selected checkbox. * Block View Prefab Path This is where the automatically generated block prefabs are located. * Block View Prefabs This is where to reference the automatically generated block prefabs. No need to change. * Dialog Prefabs This is where to reference all the dialog prefabs. * BlockViewSettings * This is where to tweak the look of blocks. There's no need to change this unless absolutely necessary