Settings
Autocomplete
Engine type
[▓░░] EXACT : start equal.[▓▓░] FUZZY : this the word. (default)
[▓▓▓] AKIN : similar words.
Order
[▓░░] OFF : none, disable.[▓▓░] SIMPLE : this the word.
[▓▓▓] SIMILAR : similar words. (default).
The most demanding options have cache memory, so the calculation of searching for something is performed once.
Documentation
- This IDE downloads files and stores them in the LocalStorage for faster uploads.
IDE does not respond:
clear the database to redownload it or refresh the page.
IDE supports & features:
- Autocomplete.
- File manager.
- Syntax Highlighter.
- Preview of errors.
- Compiles for Android and PC.
- Connection with Library::SannyBuilder and data::CrossPlataform
Syntax for conditions
Primitive
This is the most primitive way for the compiler to interpret code.IF 0 condition ELSE_GOTO @Label_false body_is_true GOTO @End :Label_false body_is_false :EndThe entire read stream moves through the conditions and jump points(labels).Sugared
The IDE has syntactic sugar to prevent us from getting too dizzy, although for now there are very few of these. You can nest them inside each other without any problem.IF condition THEN body END IF condition THEN is_true ELSE is_false ENDYou can also apply several conditions. You only have to indicate if you want to do an AND or OR check. You have a maximum of 8 conditionsIF (AND|OR) condition_1 condition_2 condition_n+1 THEN body ENDTernary
The syntax comes from JS and since commands can only be typed 1 per line, the IDE allows you to allow the false ternary.a_contition ? is_true a_condition ? is_true : is_falseCan also be used to assign a value to a variablevar = a_condition ? is_true : is_falseFor now only one condition, but support for more will be coming soon.Syntax for loops
You can work with labels.:Loop body GOTO @LoopOr use automated processes.WHILE condition body END REPEAT body UNTIL condition FOR var = start <TO|TODOWN> final [STEP (int|float)] body END FOREACH var_array body ENDloop controls are also hereBREAK CONTINUE FOR 0@ = 0 TO 10 IF 0@ > 3 THEN CONTINUE // jump a loop END IF 0@ > 7 THEN BREAK // exit of loop END ENDThere is only one difference. The `WHILE FALSE` loops are not ignored by the compiler, and are compiled as a separate area of the main flow. Their contents are only accessed if you have jumps into their body.0@ = 0 WHILE FALSE :Suma 0@++ return END printf "0@ = %i" 1s 0@ // 0 gosub @suma wait 1s printf "0@ = %i" 1s 0@ // 1If you make blocks that are too big and you get lost among many `END`, you can use these fasteners:ENDIF ENDWHILE ENDFORAll of these are interpreted as the same `END`, so you can use them as worshippers or visual highlighters.Jumps and Returns
Here I will only explain that there are different ways to use a particular opcode, in simpler ways.
for example, to make simple jumps we can do this:0001: @label // opcode goto @label // keyword jump @label // sugar @label // equivalentAll variants do the same thing and the last one is useful for shorter indications, as in this case:if 0@ != 1 then @editActor else @createActor end // or !0@ ? @editActor : @createActorthere is also a special syntax for subroutines(0050) and functions(0AB1).0050: gosub @label // opcode gosub @label // keyword label() // equivalentthe opcode to be used varies depending on whether we pass parameters or expect a return.0AB1: cleo_call @label input 1 params 0@ 0@ = label() // funcion 0@ = label(1@) // funcion label(0@) // function label() // subrutineOpcodes and Keywords
Opcodes
if you explore opcodes in documentations and forums, you don't need to memorize the 4 characters of the opcode or just copy it.0: nop --> 0000: nop FE: actor[...] --> 00FE: actor[...] !7F: car[...] --> 807F: car[...] 1234: wxyz --> 1234: wxyzKeywords
This is another way to write opcodes, you just write its name and then it is replaced by the opcode.nop --> 0000: nop WAIT 0 --> 0001: wait 0 ms not xyz 0@ --> 8ABC: !xyz 0@[...]These can be written in lowercase or uppercase, and can be negated or contradicted by placing at the beginning of the line one of these 2 executors `!, NOT`.
The IDE also detects if a keyword was written from right to left and corrects it so that it is compileable.0@ = get_current_time // is equivalent to get_current_time = 0@Classes and Flows
Classes
The IDE is connected to 2 databases to be able to script with legacy or enchanted commands. So if we use aaa.bbb() and ccc.ddd() they will use the same opcode.Normal: CLASS.MEMBER(PARAM, VAR) Method: CLASS.MEMBER Conditional: CLASS.MEMBER(PARAM) == VAR Setter: CLASS.MEMBER(PARAM) = VAR Getter: VAR = CLASS.MEMBER(PARAM)The compiler does not know the order of the custom parameters, but instead interprets the orders, depending on how the classes are used.
Everything that is located before the class is relocated at the end of the class.Multi-Geting: VAR1 VAR2 = CLASS.MEMBER(PARAM) VAR1, VAR2 = CLASS.MEMBER(PARAM)You also do not need to use commas(,) to separate the data. The compiler can detect the change of the data type, using the spaces.
The compiler remembers which was the last class used, so if you use a dot (.) at the beginning of the line, you will access the member of that class.Last-Used: .MEMBER(PARAM)Flows
Keywords that define the workflow and how it should behave on different occasions.IF, THEN, ELSE, END, WHILE, REPEAT, UNTIL, FOR, TRUE, FALSE, UNDEFINED, BREAK, CONTINUE, FOREACH, NOT, NULLAvoid naming things with these words, the order of how the text preprocessor is executed may break the script.Constants and Enumerations
These are just a nice way to read our code better, so we don't have so many numbers or confusing statements in our code. They are like keywords or classes, which only represent a value and cannot be modified.// constants TRUE = 1 _Player = $PLAYER_ACTOR PI = 3.14159265 // enumerations PEDTYPE.CIVMALE = 4 KEYCODE.R = 82 BODYPART.TORSO = 1Directives
Directives allow you to configure the compiler for various things. Within Sanny builder, to specify how each opcode should be compiled, prevent the current script from compiling without leaving the source code, import files as extensions of the same, and other things that are not very important. In EIDE there is only one direct{$I ‹source›} or {$INCLUDE ‹source›}It is used to import files into the one we have open. The compiler replaces the text and copies the content of the file that we pass as a parameter and pastes it in the place where we invoke it.Comments
Comments are lines or sections of code that are removed when compiling the code. They help us leave messages and information about where we are, what something does.Comments are lines or sections of code that are removed when compiling the code. They help us leave messages and information about where we are, what something does and also to decorate.// Only this line will be commented /* All the text in here will disappear in the compiled file */Decimals
The compiler not only has a translator for Hexadecimal and Binary numbers. It can also look up the numerical IDs of the model names.DEC -6272_48 -2936 -42 0 5 972 729_0_03 HEX -0X7FFFFF -0x8AFF 0x0 0x03 0X700000 BIN -0B011110 -0b1110 0b0 0b01 0B10000000000 OCT -0O7143 -0o1472 0o0 0o107 0O70523 TIME -2h -2m 1s 3.33S 10M 1H 60fps 30FPS NAME -#JESTER #fam1 #FAM2 #mini_gun NOTE -12E5 -3e2 1e9 10e+2 16E-3there is also a syntax for filling color fields in this way.c#123 => 11 22 33 c#123f => 11 22 33 FF c#131377 => 13 13 77 c#131377CC => 13 13 77 CCUseful for when we smell colors from the Internet and, of course, well interpreted.draw_box 1f 1f 2f 2f c#2323ABFF // traslated to draw_box 1.0 1.0 2.0 2.0 35 35 171 255Floaters
If you program in any language, you may be used to some of its syntax. Here you will be able to use it.CSS -.0025 -.97 .0 .42 .736 JS -2_823.2 0.6_608 48_386.93 PY -42.8362 -3.5 1.0 142.8638 C# -20F -13.7f 1f 27f 52.86F R -1.2E7 5.1e8 7.1e+2 9.3E-2You can begin or end a number with a period (.) or end it with `f`. Scientific notation (e) and separators (_) are also available.Literals
The editor supports the classic LONG and SHORT formats of SB, and the JS BACKSTICK.SHORT 'Abc' 09,41-62-63-00-00-00-00-00 LONG "Abc" 0E,03,41-62-63 BACKS `"Abc"` 0E,05,22-41-62-63-22Character escapes can also be made with the slash (\t, \n, \", \xff).Variables
We do not need to declare variable types, or at least in most cases.0@ = 123 // INT 0@ = 1.3 // FLOAT 0@ = '2' // SHORT 0@ = "2" // LONG 0@ = `2` // LONGYou can define the type of a variable with a prefix or subfix; I, F, S and V.This to perform precise operations.
ID TARGET USE IINT 2@i i$2FFLOAT 2@f f$2SSHORT STRING 2@s s$2VLONG STRING 2@v v$2:sumFloat 0@ += 1@ ret 1 0@ // return INT : ❌In this case, this function is expected to do a FLOAT operation, but since they are not defined, they will do an INT operation. this can be fixed, if we define the type of one.:sumFloat 0@f += 1@ ret 1 0@ // return FLOAT : 👍The IDE remembers the last variable definitions and remembers if they went from INT to FLOAT and the other way around.Locals with names
In every language there can be good and bad practices. And here things can be considered a hate crime, because of how dangerous some actions can be.int $var = 0 // ⚠️ Warning int var = 0 // 👍 PerfectThe way to declare these variables is simple: Syntax‹type› ‹name_var› [= ‹value›]Examples
- type: any type of non-array variable [int|float|short|long|string]
- name_var: Any name composed of letters, numbers, or underscores. (but they cannot begin with numbers)
- value: optional, the initial value. defaults are 0, 0.0, '' or ""
int index float accuracy= 100.0 short gxt = 'CHEAT0' long anim = "IDLE_SEAT" string foo = `banana`You can always change the data type of each variable, as long as that intention is expressed like this:int variable float variable varible // is floatIt is important to know that these variables have a scope limit.Objects
This is a type of variable data, which is used to store a collection of data, giving each property its own attributes. Syntaxobject ‹name› = { ‹type› ‹name› [ = ‹value›], ‹type› ‹name› [ = ‹value›], ... }Examples
- name: The name of the object variable.
- type: type of data that stores a property.
- value: optional, any value. defaults to 0 or empty strings.
// initialization object Camera = { int flags, float speed = 1.5 } // re assigned Camera.flags = 28 // in constant const SPEED = Camera.speed SPEED = 2.0This multiplies its potential use as an array with these data structures. But you can't put arrays into objects.Arrays
Everyone already knows the syntax for writing an ARRAY in Sanny Builder, and if you don't, I'll show it here with an example.var_main(var_index,size_and_type) example: 0@(1@,20i)And we can use it anywhere as a common variable.
Sanny, is extremely strict with syntaxes and does not support writing spaces in them, so if you make any assignment or anything, you must write it like this0@(1@,20i) = 123Enchanti offers a little more flexibility here. It does not require you to set the type of the data collection, (INT, FLOAT, SHORT, LONG) nor does it require you to set the size of the collection.0@(1@) = '2' 0@(1@,20) = "2" 0@(1@, 20) = `2` 0@f(1@,20) = 1.3 0@(1@,20i) = 123 0@(1@,20)f = 1.3 float 0@(1@,20) = 1.3If you don't specify the type, the IDE will try to know what data you want to store. Be careful though, it only works for assigning constant data for the moment.
If you do not specify the size, the IDE will set the number to 20, by default.
Constants are not left out. They are also supported and you can set their type as you see fit.a(b) = '2' a(b,20) = "2" a(b, 20) = `2` a(b,20)f = 1.3 a(b,20i) = 123 float a(b,20) = 1.3Enhanti
The most beautiful way to code. Syntax definition‹type› ‹name_var›[length] [= ‹values›]Syntax manipulation
- type: the only type of data that the array stores.
- name_var: any variable name.
- length: optional, the length of the array. if not defined, the number of elements in `values` will be taken
- values: optional, all values are blank.
‹name_var›‹index›Examples
- name_var: any defined array variable.
- index: any variable or number from 0 to the maximum of the array.
// method 1 int Integers = [true, false] // method 2 float Floaters[5] Floaters[2] = 32 // method 3 string Texts[2] = ["hello", "world"] // method 4 int index = 1 Texts[index] = "mati"Declarations and assignments are similar to real programming languages. The length number starts at 0, and the location at 1, and the length cannot be 0 or it will be invalid.Matrixes
There is also support for 2D arrays and the same syntaxes are shared.int Matrix[3][3] = [[1,2,3],[4,5,6],[7,8,9]] i = 2 Matrix[i][2] = 5Objets
It is not possible to make a 2d array at the same time as an array of objects. But at least you can make an array of Objects.
Instead of using the `object` keyword we will use `class` to define the structure of our array and we will not pass any value to it:class IEntity = { int type, int flags }and now we just write the object as if it were a data type and we don't pass any values to it either:IEntity entities[10]With this we already have a collection of objects and we can easily access each one, writing it in these ways// method 1 entities[3].type = PEDTYPE.CIVMALE // method 2 const Pedro = entities[2] Pedro.flags = 0b1110 // method 3 index = 1 actores[index].type = PEDTYPE.GANG1Hexadecimals
The IDE works with the same syntax as SB, with some limitations. You cannot insert variables yet, but you can use the hex multiplication operators :)HEX 0 00 0(2) ---> 00 00 00 00 "hello" ---> 68 65 6C 6C 6F `hello` ---> 68 65 6C 6C 6F 'hello' ---> 68 65 6C 6C 6F 00 ENDThe multiplication function, accepts arithmetic operations and rounds them to the nearest number.hex 0(4) ---> 00 00 00 00 0(4*2) ---> 00 00 00 00 00 00 00 00 0(4.6) ---> 00 00 00 00 00 0(4.3) ---> 00 00 00 00 endOperatives
Sanny
You have all the SB expressions and one extra.0@++ --> 000A: 0@ += 1 0@ <> 1@ --> 803A: 0@ != 1@ 0@ = 1@ --> 0085: 0@ = 1@ 0@ = 1@ + 2@ --> 0A8E: 0@ = 1@ + 2@ // int 0@f = 1@ + 2@--> XXXX: 0@ = 1@ + 2@ // float 0@ =# 1@ --> 0092: 0@ = int_to_float 1@ 0@ =& 1@ --> 0AC7: 0@ = var 1@ pointer 0@ +=@ 1@ --> 007B: 0@ += delta_time * 1@ 0@ &= 1@ --> 0B17: 0@ &= bit 1@the compiler remembers the data type of each manually assigned variable, so you don't have to worry about the opcode used.
you can also force a change of operation, adding a subfix (I or F) in the variable0@f++ --> XXXX: 0@ += 1.0 0@f <> 1@ --> XXXX: 0@ != 1@ 0@ = 1@f --> XXXX: 0@ = 1@ 0@ =# 1@f --> XXXX: 0@ = float_to_int 1@ float 0@ = 1@--> XXXX: 0@f = 1@Enchanti
if only one variable is written in a line, it is passed as a condition.0@ --> 0039: 0@ == true !0@ --> 0039: 0@ == falseif you write any operation backwards, the IDE will try to put the operation in the correct order.1 = 0@ --> 0@ = 1 1 == 0@ --> 0@ == 1 1 += 0@ --> 0@ += 1You can also assign a negated value to the variables, or see is truthy.0@ = !1@ --> 1@ == 1 ? 0@ = 0 : 0@ = 1 0@ = !!1@ --> 1@ == 0 ? 0@ = 1 : 0@ = 0 0@ = 1@t --> 1@ != 0 ? 0@ = 1 : 0@ = 0Or why not, your own condition? ;)0@ = 1@ == 2@ // is equivalent to 0@ = 1@ == 2@ ? true : falseFixed and temporary assignment operators are also available anywhere in the code.Car.Exist(0@(++1@,10i)) // is compiled before the line 1@ += 1 Car.Exist(0@(1@,10i)) --- Actor.Angle = 1@f++ // is compiled after the line Actor.Angle = 1@ 1@ += 1.0 --- wait 1@+30fps // is compiled before and after the line 1@ += 30fps wait 1@ 1@ -= 30fpsThis syntax only discriminates spaces and commas.
And cascading operations can also be performed in this manner1@ = 3 * 5 + 6 // is compiled at cascade in the line 1@ = 3 1@ *= 5 1@ += 6Parameters
The IDE can identify when an opcode has extra or missing parameters.nop // ok -> 00 00 wait // error -> missing params wait 0 // ok -> 01 00 04 00whenever extra parameters are entered in opcodes that do not allow them, the latter will be removed.wait 0 33 22 -> wait 0Of course, this does not affect opcodes with undefined number of parameters.cleo_call @func params 1 enter 0x0ABut let's imagine that an opcode is not found in the IDE database.
In this case, the IDE will auto-assign the number of parameters to a fixed one and depending on the number of parameters it used the first time it was invoked.XXXX: gg 3@ // ok // OP:XXXX = 1 param XXXX: gg 24@ 33 // error // OP:XXXX has 1 param, not 2.It can adapt its parameter limiter according to your needs, so you can write a single script for Android and PC.WRITE_MEMORY 1 2 3 // missing (1||2) parameters WRITE_MEMORY 1 2 3 4 // ok, for PC WRITE_MEMORY 1 2 3 4 5 // ok, for Android WRITE_MEMORY 1 2 3 4 5 6 // is cleaner and ok LOAD_ALL_STREAMING_MODELS // is mobile and occupy the same opcodeCommand finder with IA
Let's be honest, there is no AI like Copilot here, but a simple scoring algorithm, which searches for the title or description closest to our request.
Syntax// ‹message› (??|??)This is a built-in tool in the editor. So to use it, you just have to position yourself on a line that has no written content, and proceed to make a comment.
Here you just describe what you need (in English) and when you finish, end the line with '??' to ask for an opcode and it will appear with the commented parameters. Example// create a actor??Result// create a actor CREATE_CHAR {PedType} {model_char} {float} {float} {float} = {var_any} //Creates a character at the specified location, with the specified model and pedtypeor '!!' to auto-complete them with usage examples.
Example// create a actor!!ResultCREATE_CHAR PEDTYPE.CIVMALE [model_char] 23.56 21.87 44.94 = $I0J
The IDE limits some features for better performance.
- The syntax highlighter only colors the lines near the cursor.
- Autocomplete is limited to displaying a maximum of 400 results.
- Autocomplete is only rendered if 0.2 seconds have passed since the last keystroke.