Re-wrote the whole Text Script page.
commited
commit
fc60175c57093a3cfe7cb5b9023b0a18789c6506
... | ... | @@ -1,467 +1,179 @@ |
1 |
Fancade games are made with drag-n-drop of functional building blocks. A sort of visual programming suitable for touch screen devices, if you will. |
|
1 |
Hi, there. If you're curious about what Fanscript is, it is basically a system where you drag-and-drop blocks and connect wires to create what we call "scripts" when they're just a bunch of blocks, really. |
|
2 | 2 | |
3 | This page, however, describes a unofficial psuedo code text format, inspired by Fancade's script blocks made by @Isaglish, @JP16D, @Qma, and @Vex Ave on Discord. |
|
3 | Similar systems have been used by other programs such as Scratch. And tell you what; all games you see inside Fancade? They're all made with those blocks! How cool is it? |
|
4 | 4 | |
5 | [[_TOC_]] |
|
6 | ||
7 | # Fancade Coding Text Format |
|
5 | # Note |
|
6 | This is a pseudo-code you use to write in Discord instead of having to go back to Fancade, screenshot the scripts, then go back to Discord and send it. If you don't understand it then there's no other way but to go to Fancade and take a look at the scripts. |
|
8 | 7 | |
9 | This Format will be a basis when sharing or suggesting some codes and code solutions during script discussions. Take this as an easier way to share or suggest a code program instead doing it in fancade and go back to fancade discord server. Well in case of people that couldn't understand this... Sorry we can't do anything about it :P, no jokes! Do the thing in Fancade, screenshot it and share it to them. |
|
8 | This is also just a way to predict how Fanscript is gonna look if Martin decides to make a text language for Fancade. |
|
10 | 9 | |
10 | This page is still being re-written by @Isaglish. Ping me in Discord if you have any questions. |
|
11 | 11 | |
12 | ### Introduction |
|
13 | This format is based on C# syntax. Most of things are simplified for better understanding. |
|
14 | ||
15 | As you know, Fancade's script blocks are located in different folders. To make it easier to understand, what it means, use their names as in the example below. It's not necessary and takes such a time to write, but please pay attention to it when you're explaining script to the new user or there are namesake custom blocks. |
|
12 | [[_TOC_]] |
|
16 | 13 | |
17 | Following the C# syntax, let's imagine that each folder is a separate class with its own fields and functions. So, to represent Get Frame block, you need to type `Game.Frame`. Again, it's not necessary , just `Frame` is fine too. |
|
14 | # Folders |
|
15 | First of all, we have folders. These are the folders in your Inventory when you tap on the plus icon on the very far right of your hotbar. |
|
18 | 16 | |
19 | All the cases: |
|
20 | 17 | ```coffeescript |
21 | # If block has yellow wires, add () at the end of the name |
|
22 | Game.Win(); |
|
23 | Sound.PlaySound(); |
|
24 | ||
25 | # If block has inputs, count them and their type in the brackets |
|
26 | Objects.SetPosition(obj object, vec position, rot rotation); |
|
27 | ||
28 | # If block has more than one output you will need to define them individually |
|
29 | # Use '.outputname' after the function to define them |
|
30 | Objects.GetPosition(target_object).position; |
|
31 | ||
32 | # Math block counts like this, except the basic ones listed below |
|
33 | vec result = Math.LineVsPlane(from, to, normal, point); |
|
34 | ||
35 | # If block has only outputs, don't do anything |
|
36 | num frame = Game.Frame; |
|
18 | # if you wanna use assets you've created or |
|
19 | # use pre-existing ones then you will have to do this: |
|
20 | player = MyBlocks:Player |
|
21 | bricks = Terrain:Bricks |
|
22 | grass = Terrain:Grass |
|
23 | particle = Decor:Particle |
|
37 | 24 | ``` |
38 | 25 | |
39 | **____________________________________** |
|
40 | ### Basics |
|
41 | **____________________________________** |
|
42 | ||
43 | #### Value Types |
|
26 | # Variables |
|
44 | 27 | ```coffeescript |
45 | # Variables and Data Types |
|
46 | num varName = 0; |
|
47 | tru varName = true/false; |
|
48 | vec varName = (x , y , z); |
|
49 | rot varName = (x , y , z); |
|
50 | obj varName = MyBlocks.BlockName; |
|
51 | ||
52 | # To make global variables, simply add a $ sign as a prefix of a variable name |
|
53 | obj me = Myblocks.Me |
|
54 | vec $myPosition = Objects.GetPosition(me).position |
|
28 | # set a global variable by adding '$' at the beginning of a variable name |
|
29 | $deltaTime = Frame() |
|
55 | 30 | |
56 | # Any variable can be used as list by using the format: varName[index] |
|
57 | ||
58 | #To define wire input values use |
|
59 | wire_wireName = value |
|
60 | #This can be use In case of functions that uses another functions to their inputs |
|
61 | #so that it doesn't look very messy unlike when directly placing them |
|
62 | #(can this thing be called the spaghetti wires in text scripting 0w0) |
|
31 | # similar to global variables, saved variables have a '!' at the prefix |
|
32 | # note that this only works for Numbers type at the moment |
|
33 | !coinMultiplier = MenuItem("Coin Multiplier", "on/off", "10 double") |
|
63 | 34 | |
35 | # in fancade, we have six different data types |
|
36 | # variables are dynamic so you don't have to specify their type |
|
37 | age = 10 |
|
38 | gunSprite = MyBlocks:Pistol |
|
39 | positionOffset = Vector(x, y, z) |
|
40 | angle = Rotation(x, y, z) |
|
41 | banned = False |
|
42 | constraint = AddConstraint(base, part, pivot) |
|
64 | 43 | ``` |
65 | **____________________________________** |
|
66 | ||
67 | #### Basic Math Operators |
|
68 | **____________________________________** |
|
69 | 44 | |
45 | # How to use each block in each folder |
|
46 | ## Game folder |
|
70 | 47 | ```coffeescript |
71 | # Add Numbers |
|
72 | 2 + 2 |
|
48 | Win(delay) |
|
73 | 49 | |
74 | # Subtract Numbers |
|
75 | 2 - 2 |
|
50 | Lose(delay) |
|
76 | 51 | |
77 | # Multiply Numbers |
|
78 | 2 * 2 |
|
52 | SetScore(score, coins, "Most Points") |
|
79 | 53 | |
80 | # Divide Numbers |
|
81 | 2 / 2 |
|
54 | SetCamera(position, rotation, range) |
|
82 | 55 | |
83 | # Power |
|
84 | 2 ^ 2 |
|
56 | SetLight(rotation) |
|
85 | 57 | |
86 | # Modulo |
|
87 | 2 % 2 |
|
58 | screenWidth = ScreenSize().width |
|
59 | screenHeight = ScreenSize().height |
|
88 | 60 | |
89 | # Increase |
|
90 | num++ |
|
91 | ||
92 | # Decrease |
|
93 | num-- |
|
94 | ``` |
|
95 | **____________________________________** |
|
96 | ||
97 | #### Basic Boolean Operators |
|
98 | **____________________________________** |
|
99 | ```coffeescript |
|
100 | # Boolean logic (and, or, not) |
|
61 | direction = Accelerometer() |
|
101 | 62 | |
102 | tru fruit = ((not lettuce) and (orange)) or apple; |
|
63 | delta = Frame() |
|
103 | 64 | |
104 | # Math (Greater, Less, Equal) |
|
105 | ||
106 | tru equal = a == b; |
|
107 | ||
108 | tru greater = a > b; |
|
109 | ||
110 | tru less = a < b; |
|
65 | !item = MenuItem(picture, "The name of your item", "on/off", "10 double") |
|
111 | 66 | ``` |
112 | 67 | |
113 | **____________________________________** |
|
114 | ||
115 | ### Game |
|
116 | **____________________________________** |
|
68 | ## Objects folder |
|
117 | 69 | ```coffeescript |
118 | Game.Win(); |
|
70 | objectPosition = GetPosition(object).position |
|
71 | objectRotation = GetPosition(object).rotation |
|
119 | 72 | |
120 | Game.Lose(); |
|
73 | SetPosition(object, position, rotation) |
|
121 | 74 | |
122 | Game.SetScore(num Score, num Coins).MostPoints; |
|
123 | # SetScore extensions: |
|
124 | .MostPoints |
|
125 | .FewestPoints |
|
126 | .FastestTime |
|
127 | .LongestTime |
|
75 | hit = Raycast(from, to).hit |
|
76 | hitPosition = Raycast(from, to).hitpos |
|
77 | hitObject = Raycast(from, to).hitobj |
|
128 | 78 | |
129 | # Add an .Perspective extension if it is enabled. if it isn't, then don't do anything |
|
130 | Game.SetCamera(vec Position, rot Rotation, num Distance).Perspective; |
|
79 | objectSizeMin = GetSize(object).min |
|
80 | objectSizeMax = GetSize(object).max |
|
131 | 81 | |
82 | SetVisible(object, visible) |
|
132 | 83 | |
133 | Game.SetLight(vec Position, rot Rotation); |
|
84 | copiedObject = CreateObject(original) |
|
134 | 85 | |
135 | Game.ScreenSize.x |
|
136 | Game.ScreenSize.y |
|
137 | ||
138 | Game.Accelerometer |
|
139 | ||
140 | Game.Frame |
|
86 | DestroyObject(object) |
|
141 | 87 | ``` |
142 | 88 | |
143 | **____________________________________** |
|
144 | ||
145 | ### Objects |
|
146 | **____________________________________** |
|
89 | ## Sounds folder |
|
147 | 90 | ```coffeescript |
148 | Objects.GetPosition(obj).position |
|
149 | Objects.GetPosition(obj).rotation |
|
150 | ||
151 | Objects.SetPosition(obj Object, vec position, rot Rotation); |
|
91 | channel = PlaySound(volume, pitch).channel |
|
152 | 92 | |
153 | # alternatives |
|
93 | StopSound(channel) |
|
154 | 94 | |
155 | # Set Position |
|
156 | obj.position = vec; |
|
157 | obj.rotation = rot; |
|
158 | ||
159 | # Get Position |
|
160 | vec = obj.position; |
|
161 | rot = obj.rotation; |
|
162 | ||
163 | Objects.Raycast(vec, vec).hit |
|
164 | Objects.Raycast(vec, vec).hitPos |
|
165 | Objects.Raycast(vec, vec).hitObj |
|
166 | ||
167 | Objects.GetSize(obj Object).min |
|
168 | Objects.GetSize(obj Object).max |
|
169 | ||
170 | Objects.CreateObject(obj Object); |
|
171 | ||
172 | Objects.DestroyObject(obj Object); |
|
95 | VolumePitch(channel, volume, pitch) |
|
173 | 96 | ``` |
174 | 97 | |
175 | **____________________________________** |
|
176 | ||
177 | ### Sound |
|
178 | **____________________________________** |
|
98 | ## Physics folder |
|
179 | 99 | ```coffeescript |
180 | Sound.PlaySound(num Volume, num Pitch); |
|
181 | num sfx = Sound.PlaySound(num Volume, num Pitch).channel |
|
100 | AddForce(object, force, applyAt, torque) |
|
182 | 101 | |
183 | Sound.StopSound(num Channel); |
|
102 | velocity = GetVelocity(object).velocity |
|
103 | spin = GetVelocity(object).spin |
|
184 | 104 | |
185 | Sound.VolumePitch(num Channel, num Volume, num Pitch); |
|
186 | ``` |
|
105 | SetVelocity(object, velocity, spin) |
|
187 | 106 | |
188 | **____________________________________** |
|
107 | SetLocked(object, position, rotation) |
|
189 | 108 | |
190 | ### Physics |
|
191 | **____________________________________** |
|
192 | ```coffeescript |
|
193 | Physics.AddForce(obj Object, vec Force, vec applyAt, vec Torque); |
|
194 | ||
195 | vec playerVelocity = Physics.GetVelocity(obj Object).velocity; |
|
196 | vec playerVelocity = Physics.GetVelocity(obj Object).spin; |
|
197 | ||
198 | Physics.SetVelocity(obj Object, vec Force, vec Spin); |
|
199 | ||
200 | Physics.SetLocked(obj Object, vec Position, vec Rotation); |
|
109 | SetMass(object, mass) |
|
201 | 110 | |
202 | Physics.SetMass(obj Object, num Mass); |
|
111 | SetFriction(object, friction) |
|
203 | 112 | |
204 | Physics.SetFriction(obj Object, num Friction); |
|
113 | SetBounciness(object, bounciness) |
|
205 | 114 | |
206 | Physics.SetBounciness(obj Object, num Bounciness); |
|
115 | SetGravity(gravity) |
|
207 | 116 | |
208 | Physics.SetGravity(vec Gravity); |
|
117 | constraint = AddConstraint(base, part, pivot) |
|
209 | 118 | |
210 | const constraint = Physics.AddConstraint(obj Base, obj Part, vec Pivot).constraint; |
|
119 | LinearLimits(constraint, lower, upper) |
|
211 | 120 | |
212 | Physics.LinearLimits(const Constraint, vec Lower, vec Upper); |
|
121 | AngularLimits(constraint, lower, upper) |
|
213 | 122 | |
214 | Physics.AngularLimits(const Constraint, vec Lower, vec Upper); |
|
123 | LinearSpring(constraint, stiffness, damping) |
|
215 | 124 | |
216 | Physics.LinearSpring(const Constraint, vec Stiffness, vec Damping); |
|
125 | AngularSpring(constraint, stiffness, damping) |
|
217 | 126 | |
218 | Physics.AngularSpring(const Constraint, vec Stiffness, vec Damping); |
|
219 | ||
220 | Physics.LinearMotor(const Constraint, vec Speed, vec Force); |
|
221 | ||
222 | Physics.AngularMotor(const Constraint, vec Speed, vec Force); |
|
127 | LinearMotor(constraint, speed, force) |
|
223 | 128 | |
129 | AngularMotor(constraint, speed, force) |
|
224 | 130 | ``` |
225 | 131 | |
226 | ||
227 | **____________________________________** |
|
228 | ||
229 | ### Control |
|
230 | **____________________________________** |
|
132 | ## Control folder |
|
231 | 133 | ```coffeescript |
232 | # Basic if operator |
|
233 | If (condition) { |
|
234 | function_true; |
|
235 | } else { |
|
236 | function_false; |
|
237 | } |
|
238 | ||
239 | # Loop |
|
240 | Loop(num start = 0, num end = 0) { |
|
241 | //Output |
|
242 | out.counter |
|
243 | } |
|
244 | ||
245 | # Sensors |
|
246 | TouchSensor('1st').touching { |
|
247 | //Outputs |
|
248 | out.screen.x |
|
249 | out.screen.y |
|
250 | } |
|
251 | #touch sensor has multiple extensions and fixed inputs: |
|
252 | ||
253 | # Extensions |
|
254 | .touching |
|
255 | .begins |
|
256 | .ends |
|
257 | ||
258 | #Inputs |
|
259 | "1st" or "First" |
|
260 | "2nd" or "Second" |
|
261 | "3rd" or "Third" |
|
262 | ||
263 | ||
264 | Collision(obj mainObject) { |
|
265 | //Outputs |
|
266 | out.secondObject |
|
267 | out.impulse |
|
268 | out.normal |
|
269 | } |
|
270 | ||
271 | BoxArt() { |
|
134 | If(condition) { |
|
135 | # do true stuff |
|
136 | } else { |
|
137 | # do false stuff |
|
272 | 138 | } |
273 | 139 | |
274 | 140 | PlaySensor() { |
141 | # initialize stuff here |
|
275 | 142 | } |
276 | 143 | |
277 | 144 | LateUpdate() { |
145 | # late update stuff here |
|
278 | 146 | } |
279 | ``` |
|
280 | ||
281 | **____________________________________** |
|
282 | ||
283 | ### Math |
|
284 | **____________________________________** |
|
285 | ```coffeescript |
|
286 | Math.Negate(num Num) |
|
287 | ||
288 | Math.Inverse(rot Rot) |
|
289 | ||
290 | vec.Scale(num Num) |
|
291 | ||
292 | vec.Rotate(rot Rot) |
|
293 | ||
294 | rot1.Combine(rot Rot2) |
|
295 | ||
296 | Math.Random(num Min, num Max) |
|
297 | ||
298 | Math.RandomSeed(num Seed); |
|
299 | ||
300 | Math.Min(num Num1, num Num2) |
|
301 | 147 | |
302 | Math.Max(num Num1, num Num2) |
|
303 | ||
304 | Math.Sin(num Num) |
|
305 | ||
306 | Math.Cos(num Num) |
|
307 | ||
308 | Math.Round(num Num) |
|
309 | ||
310 | Math.Floor(num Num) |
|
311 | ||
312 | Math.Ceil(num Num) |
|
313 | ||
314 | Math.Absolute(num Num) |
|
315 | ||
316 | Math.Log(num Num, num Base) |
|
317 | ||
318 | # break vectors into number variables. |
|
319 | num = vec.x |
|
320 | num = vec.y |
|
321 | num = vec.z |
|
322 | ||
323 | vec.Normalize |
|
324 | ||
325 | vec.Dot(vec Vector) |
|
326 | ||
327 | vec.Cross(vec Vector) |
|
328 | ||
329 | # break a rotation into number variables. |
|
330 | num rot.x |
|
331 | num rot.y |
|
332 | num rot.z |
|
333 | ||
334 | Math.Distance(vec Vec1, vec Vec2) |
|
335 | ||
336 | Math.LERP(rot From, rot To, num Amount) |
|
337 | ||
338 | Math.AxisAngle(vec Axis, num Angle) |
|
339 | ||
340 | Math.ScreenToWorld(num ScreenX, num ScreenY) |
|
341 | ||
342 | Math.WorldToScreen(vec WorldPos).x |
|
343 | Math.WorldToScreen(vec WorldPos).y |
|
344 | ||
345 | Math.LineVsPlane(vec From, vec To, vec Point, vec Normal) |
|
346 | ||
347 | Math.LookRotation(vec Direction, vec Up) |
|
348 | ``` |
|
349 | ### (Important!) Editing Notes |
|
350 | ***To all contributors and people who edits the Fancade Pseudo-Coding Language*** , Pls don't put too much extensions to the things as much as possible , extensions such as `Math.` or `Objects.` , this thing is very unnecessary since it will only be used in scripting discussion , unless... one of us can implement it as a real coding language ;D |
|
351 | ||
352 | # Syntax |
|
353 | ||
354 | Ever wondered how Fanscript would look in text format? Well, you can see all references in this directory! |
|
355 | ||
356 | Keep in mind that this is a Work-In-Progress project and that all codes you see will not work if you try to write it in say Unity's C#. |
|
357 | ||
358 | ## Examples |
|
359 | Datatypes consist of: |
|
360 | ||
361 | ```coffeescript |
|
362 | num Age = 10 |
|
363 | vec Position = (10, 1.51, 5) |
|
364 | rot Angle = (0, 90, 0) |
|
365 | tru Hit = True |
|
366 | obj Player = MyBlocks.Player |
|
367 | ``` |
|
368 | ||
369 | For the constraints, it'll be the same inside Fancade: |
|
370 | ||
371 | ```coffeescript |
|
372 | PlaySensor() { |
|
373 | const constraint = Physics.AddConstraint(base, part, pivot) |
|
374 | Physics.AngularLimits(constraint, (0, 0, 1), (0, 0, 0)) |
|
375 | Physics.AngularMotor(constraint, (0, 0, 90), (0, 0, 100)) |
|
148 | BoxArtSensor() { |
|
149 | # do stuff here |
|
376 | 150 | } |
377 | ``` |
|
378 | ||
379 | In total we have 7 datatypes that includes lists. |
|
380 | ||
381 | Talking about lists here is how you do them in text format: |
|
382 | ||
383 | ```coffeescript |
|
384 | # set a list variable |
|
385 | vec Positions[0] = (32.1, 5.51, -23.72) |
|
386 | ||
387 | # to access a list |
|
388 | num.Inspect(num phoneNumbers[2]) |
|
389 | ``` |
|
390 | 151 | |
391 | ## Datatypes |
|
392 | ||
393 | In Fancade we have a total of 7 datatypes. These datatypes are num, vec, rot, tru, obj, const, and list. |
|
394 | ||
395 | The number type can be either a whole number or in decimals, in the programming world we call these "int" and "float/double". |
|
396 | ||
397 | Here are some examples: |
|
398 | ```coffeescript |
|
399 | num jumpSpeed = 0.2 |
|
400 | vec level = (1, 1, -10) |
|
401 | rot fan = (0.1, 0, 0) |
|
402 | tru blocked = False |
|
403 | obj me = MyBlocks.Me |
|
404 | ``` |
|
405 | ||
406 | For the constraint, here is how you do it: |
|
407 | ```coffeescript |
|
408 | PlaySensor() { |
|
409 | const constraint = Physics.AddConstraint(base, part, pivot) |
|
410 | Physics.AngularLimits(const, (0, 0, 1), (0, 0, 0)) |
|
411 | Physics.AngularMotor(const, (0, 0, 90), (0, 0, 100)) |
|
152 | # TouchSensor returns Number x and Number y in a tuple format (x, y) |
|
153 | tapX, tapY = TouchSensor("Touching") { |
|
154 | # do stuff here |
|
412 | 155 | } |
413 | ``` |
|
414 | To create variables simply type: |
|
415 | `Datatype variableName` |
|
416 | 156 | |
417 | And to initialize: |
|
418 | `Datatype variableName = value` |
|
419 | ||
420 | For the lists here is an example: |
|
421 | ```coffeescript |
|
422 | PlaySensor() { |
|
423 | obj landmine = MyBlocks.LM |
|
424 | obj $LM[num $LM] = landmine |
|
425 | vec $LM[num $LM] = Objects.GetPosition(landmine).position |
|
426 | num $LM++ |
|
157 | direction = SwipeSensor() { |
|
158 | # do stuff here |
|
427 | 159 | } |
428 | ``` |
|
429 | 160 | |
430 | To access values inside a list: |
|
431 | ```coffeescript |
|
432 | Loop(0, $landmines) { |
|
433 | num i = self.currentIndex |
|
434 | vec landminePositions = vec $LM[num i] |
|
161 | Button("Direction") { |
|
162 | # do stuff here |
|
435 | 163 | } |
436 | ``` |
|
437 | 164 | |
438 | ### Example |
|
439 | ||
440 | Here is [[Martin Magni]]'s Shepherd game in text format. |
|
441 | ||
442 | ```coffeescript |
|
443 | # Init |
|
444 | obj $Herder = MyBlocks.Herder |
|
445 | obj Sheep = MyBlocks.Sheep |
|
446 | ||
447 | # Sheep script |
|
448 | TouchSensor("First").touching { |
|
449 | Physics.AddForce(Sheep, Math.LineVsPlane(Math.ScreenToWorld(self.screen.x, self.screen.y), (0, 2, 0), (0, 2, 0)) - Objects.GetPosition(Sheep).position) |
|
165 | Joystick("XZ") { |
|
166 | # do stuff here |
|
450 | 167 | } |
451 | 168 | |
452 | num $Dist = Math.Max(Math.Distance(Objects.GetPosition(Sheep).position, Objects.GetPosition($Herder).position), $Dist) |
|
453 | ||
454 | Collision(Sheep) { |
|
455 | If (this.secondObject == None) { |
|
456 | Game.Lose(False) |
|
457 | } |
|
169 | object, impulse, normal = Collision(object) { |
|
170 | # do stuff here |
|
458 | 171 | } |
459 | 172 | |
460 | # Herder script |
|
461 | If (num $Dist < 2) { |
|
462 | Game.Win(False) |
|
173 | counter = Loop(start, end) { |
|
174 | # do stuff here |
|
463 | 175 | } |
464 | num $Dist = 0 |
|
465 | ||
176 | ``` |
|
466 | 177 | |
467 | ``` |
|
... | ... | \ No newline at end of file |
0 | ## Math folder |
|
1 | work-in-progress |
|
... | ... | \ No newline at end of file |