Skip to content

Commit 6da9463

Browse files
authored
(Docs) Your First Project (#415)
1 parent 3799658 commit 6da9463

File tree

2 files changed

+280
-1
lines changed

2 files changed

+280
-1
lines changed
Lines changed: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,278 @@
1+
To start, let's quickly take a look at a vertical slice of Fusion code. You'll
2+
see how everything looks together, but you aren't expected to understand
3+
everything right away.
4+
5+
-----
6+
7+
## Overview
8+
9+
Open a new script file and ensure you have Fusion imported correctly.
10+
11+
```Lua linenums="1"
12+
local ReplicatedStorage = game:GetService("ReplicatedStorage")
13+
local Fusion = require(ReplicatedStorage.Fusion)
14+
```
15+
16+
### Your first scope
17+
18+
Fusion is a library where you will be creating a lot of objects. Fusion groups
19+
these objects together so they can be managed in bulk.
20+
21+
If you've used other Luau libraries before, this idea goes by many names, like
22+
"maids" or "janitors". However, in Fusion, we call them *scopes*.
23+
24+
Let's start by creating a scope for ourselves.
25+
26+
```Lua linenums="1" hl_lines="4"
27+
local ReplicatedStorage = game:GetService("ReplicatedStorage")
28+
local Fusion = require(ReplicatedStorage.Fusion)
29+
30+
local scope = Fusion:scoped()
31+
```
32+
33+
### Your first value
34+
35+
Now, we will create our first Fusion object - the *value*. As the name suggests,
36+
values are very simple objects; they store a single value, much like a variable.
37+
38+
Call the `:Value()` function on the scope to create a value, and give it
39+
something to be stored.
40+
41+
```Lua linenums="4" hl_lines="3"
42+
local scope = Fusion:scoped()
43+
44+
local numCoins = scope:Value(50)
45+
```
46+
47+
### Peeking
48+
49+
Fusion gives you a global utility that can peek inside of these objects and see
50+
what they're currently storing at this moment in time. It's useful for debugging
51+
your code, or otherwise checking something's contents without causing anything
52+
else to happen.
53+
54+
By using `Fusion.peek`, we can read and print out the contents of `numCoins`.
55+
56+
```Lua linenums="4" hl_lines="5"
57+
local scope = Fusion:scoped()
58+
59+
local numCoins = scope:Value(50)
60+
61+
print(Fusion.peek(numCoins)) --> 50
62+
```
63+
64+
### Running a computation
65+
66+
Let's try running a computation instead. To do this, we will create a
67+
second Fusion object - the *computed*.
68+
69+
Call the `:Computed()` function on the scope to create a computed, and give it
70+
a function to run as a calculation. For now, it'll just be hardcoded.
71+
72+
```Lua linenums="4" hl_lines="5-7"
73+
local scope = Fusion:scoped()
74+
75+
local numCoins = scope:Value(50)
76+
77+
local message = scope:Computed(function()
78+
return "I am a message"
79+
end)
80+
81+
print(Fusion.peek(numCoins)) --> 50
82+
```
83+
84+
As with values, computeds can be peeked at, to see their contents without doing
85+
anything else.
86+
87+
Let's change the print statement to show the message instead.
88+
89+
```Lua linenums="4" hl_lines="9"
90+
local scope = Fusion:scoped()
91+
92+
local numCoins = scope:Value(50)
93+
94+
local message = scope:Computed(function()
95+
return "I am a message"
96+
end)
97+
98+
print(Fusion.peek(message)) --> I am a message
99+
```
100+
101+
### Adding other objects to the computation
102+
103+
Let's change the message to show how many coins we have. To use another object
104+
in your calculation, computeds will give you a `use` parameter.
105+
106+
Add this `use` parameter to your computed callback.
107+
108+
```Lua linenums="4" hl_lines="5"
109+
local scope = Fusion:scoped()
110+
111+
local numCoins = scope:Value(50)
112+
113+
local message = scope:Computed(function(use)
114+
return "I am a message"
115+
end)
116+
117+
print(Fusion.peek(message)) --> I am a message
118+
```
119+
120+
`use` is a function that you can pass a Fusion object to, and it will give you
121+
the value, similarly to `peek`. However, unlike `peek`, it will also link your
122+
computation to that other Fusion object under the hood.
123+
124+
Let's change our message to tell us the number of coins:
125+
126+
```Lua linenums="4" hl_lines="6"
127+
local scope = Fusion:scoped()
128+
129+
local numCoins = scope:Value(50)
130+
131+
local message = scope:Computed(function(use)
132+
return "The number of coins is " .. use(numCoins)
133+
end)
134+
135+
print(Fusion.peek(message)) --> The number of coins is 50
136+
```
137+
138+
### Updating your data
139+
140+
Suppose we want to give the user more coins.
141+
142+
Values specifically have a `:set()` method that can be used to change the data
143+
they are storing.
144+
145+
Let's use this at the end and re-print the message.
146+
147+
```Lua linenums="4" hl_lines="11-13"
148+
local scope = Fusion:scoped()
149+
150+
local numCoins = scope:Value(50)
151+
152+
local message = scope:Computed(function(use)
153+
return "The number of coins is " .. use(numCoins)
154+
end)
155+
156+
print(Fusion.peek(message)) --> The number of coins is 50
157+
158+
numCoins:set(75)
159+
160+
print(Fusion.peek(message)) --> The number of coins is 75
161+
162+
```
163+
164+
### Detecting changes
165+
166+
Right now, we intend to print the message whenever the message changes. It would
167+
be nice to do that automatically.
168+
169+
To do that, Fusion has a third kind of object - the *observer*.
170+
171+
Call the `:Observer()` function on the scope to create an observer, and pass the
172+
object you want the observer to watch and detect changes to.
173+
174+
```Lua linenums="4" hl_lines="9"
175+
local scope = Fusion:scoped()
176+
177+
local numCoins = scope:Value(50)
178+
179+
local message = scope:Computed(function(use)
180+
return "The number of coins is " .. use(numCoins)
181+
end)
182+
183+
scope:Observer(message)
184+
185+
print(Fusion.peek(message)) --> The number of coins is 50
186+
187+
numCoins:set(75)
188+
189+
print(Fusion.peek(message)) --> The number of coins is 75
190+
```
191+
192+
To add a callback that runs when a change is detected, call `:onChange()` on the
193+
observer with the callback you want - we'll print the message inside ours, and
194+
get rid of the old prints.
195+
196+
```Lua linenums="4" hl_lines="9-11"
197+
local scope = Fusion:scoped()
198+
199+
local numCoins = scope:Value(50)
200+
201+
local message = scope:Computed(function(use)
202+
return "The number of coins is " .. use(numCoins)
203+
end)
204+
205+
scope:Observer(message):onChange(function()
206+
print(Fusion.peek(message))
207+
end)
208+
209+
numCoins:set(75)
210+
211+
--> The number of coins is 75
212+
```
213+
214+
The message gets printed after we change the number of coins!
215+
216+
If you want to print the message immediately, too, use `:onBind()` instead:
217+
218+
```Lua linenums="4" hl_lines="9"
219+
local scope = Fusion:scoped()
220+
221+
local numCoins = scope:Value(50)
222+
223+
local message = scope:Computed(function(use)
224+
return "The number of coins is " .. use(numCoins)
225+
end)
226+
227+
scope:Observer(message):onBind(function()
228+
print(Fusion.peek(message))
229+
end)
230+
231+
--> The number of coins is 50
232+
233+
numCoins:set(75)
234+
235+
--> The number of coins is 75
236+
```
237+
238+
### Tidying up
239+
240+
Our Fusion code is feature-complete, but before it stops running, we want to
241+
delete everything we've made to ensure we aren't consuming resources forever.
242+
243+
Luckily, that's very simple. When you're done with all of the objects in a scope,
244+
you can destroy the scope all in one go with `scope:doCleanup()`.
245+
246+
```Lua linenums="4" hl_lines="19"
247+
local scope = Fusion:scoped()
248+
249+
local numCoins = scope:Value(50)
250+
251+
local message = scope:Computed(function(use)
252+
return "The number of coins is " .. use(numCoins)
253+
end)
254+
255+
scope:Observer(message):onBind(function()
256+
print(Fusion.peek(message))
257+
end)
258+
259+
--> The number of coins is 50
260+
261+
numCoins:set(75)
262+
263+
--> The number of coins is 75
264+
265+
scope:doCleanup()
266+
```
267+
268+
Just like that, everything you've made with `scope:` gets dismantled and stops
269+
running.
270+
271+
-----
272+
273+
With that, you've written your first file of Fusion code, touching on all of the
274+
major Fusion concepts!
275+
276+
Over the next few tutorials, we'll dig deeper into what exactly all of this code
277+
is doing, but for now, feel free to review these code snippets as many times as
278+
you need.

mkdocs.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,11 @@ nav:
5959
- Developer Tools: tutorials/get-started/developer-tools.md
6060
- Getting Help: tutorials/get-started/getting-help.md
6161
- Fundamentals:
62-
- Scopes: tutorials/fundamentals/scopes.md
62+
- Your First Project: tutorials/fundamentals/your-first-project.md
6363
- Values: tutorials/fundamentals/values.md
6464
- Observers: tutorials/fundamentals/observers.md
6565
- Computeds: tutorials/fundamentals/computeds.md
66+
- Scopes: tutorials/fundamentals/scopes.md
6667
- Tables:
6768
- ForValues: tutorials/tables/forvalues.md
6869
- ForKeys: tutorials/tables/forkeys.md

0 commit comments

Comments
 (0)