How I Designed a Scalable Skill Tree System | Roblox Studio — Transcript
Full transcript
- 0:00Over the last few days, I have been
- 0:01working on a little system that I think
- 0:03you guys will really enjoy learning
- 0:05about and that is my skill tree system
- 0:08that is heavily inspired by the one in
- 0:10Empire. But before I get into today's
- 0:12video, if you guys do go on to enjoy or
- 0:15learn something from this video, please
- 0:17leave a like and subscribe. But let's
- 0:18get into the skill tree.
- 0:21So, the first thing you will see is the
- 0:23skill tree area, which is made out of
- 0:26physical parts and there is nothing with
- 0:28UI in this system. So, the first
- 0:31question you guys might have is why
- 0:33would I do that? Well, one reason it
- 0:34just looks better because having
- 0:36everything 2D might look a little flat.
- 0:38For example, we have these glowing rings
- 0:40around the buttons and overall, I think
- 0:42using physical parts just makes it look
- 0:45a lot better and adds more.
- 0:47But this does come with a little cost
- 0:50and that is setting up everything. So,
- 0:52as you can see, we have these four
- 0:54buttons here, but also we have some
- 0:56invisible ones in their respective
- 0:58colors.
- 0:59So, we have all of these buttons and
- 1:01connector beams already in their folder,
- 1:05but you can't see all of them and the
- 1:07reason why I did this is I wanted to
- 1:09keep things as simple and easy to
- 1:11configure as possible without making
- 1:13everything complicated and having to
- 1:15store a lot of information about
- 1:17positions and how to handle the buttons.
- 1:21So, that is why everything is already
- 1:23laid out here and just the buttons
- 1:26that you haven't unlocked yet aren't
- 1:27visible and the information we do have
- 1:30though in these buttons is we have a
- 1:33connector attribute and the next node
- 1:36attribute. So, each node
- 1:39points has an attribute that points to
- 1:42the next node and also has a connector
- 1:44attribute that points to the connector
- 1:46that connects the next button, if that
- 1:49makes any sense.
- 1:50But if it is the last node in the tree
- 1:54of for the color, then the connector and
- 1:57next node attributes are just empty.
- 2:00So, going back to that cost that comes
- 2:03with using physical parts, a part of
- 2:05that is making custom systems like this
- 2:08custom camera drag module that controls
- 2:11the movement of the camera when we are
- 2:12in skill tree mode. And so, this is kind
- 2:16of lengthy,
- 2:17200 lines long, roughly, but it's for
- 2:20good reason because this module handles
- 2:23the camera movement on all devices.
- 2:26So, it's very basic. We have a start and
- 2:29stop function. And so, when we start the
- 2:32camera drag, we are just checking if
- 2:34there is touch enabled, like if they are
- 2:36on mobile, then we just hide the touch
- 2:38GUI to make it easier for mobile
- 2:40players, set the camera type and CFrame
- 2:42to set up the camera. And then, I am not
- 2:46using any connection managers, so I'm
- 2:49putting everything into a table and then
- 2:52disconnecting them later. I know
- 2:55I'm going to get ridiculed in the
- 2:56comments for that, but anyways,
- 2:58when we scroll with our mouse, then it
- 3:01controls a zoom target variable, which
- 3:04we will handle later on in the script. I
- 3:06will show you guys that. And also, mouse
- 3:09button one down,
- 3:10we are just detecting
- 3:12the drag and while we are dragging, then
- 3:15it sets this pan target variable using
- 3:19this delta variable and new speed.
- 3:22And then coming down here, once again,
- 3:24we are detecting if the user is on
- 3:26mobile. So, if user input
- 3:28service.gamepadenabled and if they are,
- 3:29then we're going to add two more
- 3:31connections, which is touch pan and
- 3:33touch pinch, which allows us to move the
- 3:35camera on mobile. And also, if the
- 3:37mobile player wants to, then they can
- 3:40pinch their screen and they can zoom in
- 3:43and out just like you would on PC with
- 3:45your mouse wheel.
- 3:47And then coming down here is where
- 3:49basically all the magic happens. So, in
- 3:51run service.prerender,
- 3:53remember up here we were setting zoom
- 3:55target and pan target.
- 3:58And the zoom target, well, down here is
- 4:01where we actually make everything smooth
- 4:03and resolve everything.
- 4:05But before we actually get to that,
- 4:07which is down here, we first handle
- 4:09console movement. So, as you can see
- 4:12here, if user input
- 4:14service.gamepadenabled,
- 4:15then we will set up the gamepad
- 4:17functionality, which I will hop in and
- 4:19show you guys how that works as well.
- 4:21But down here is where all the magic
- 4:24happens. So, we are basically just
- 4:27smoothly moving the current pan position
- 4:29toward the target position using lerp.
- 4:32So, this allows us to smoothly move our
- 4:35camera around and also zoom current
- 4:37allows us to zoom in and out smoothly.
- 4:41And then finally, setting the camera
- 4:43CFrame to all of these new values and
- 4:45also multiply it by the camera
- 4:46orientation to keep that same
- 4:48orientation. And then we have stop,
- 4:51which just disconnects everything,
- 4:52cleans everything up and resets
- 4:54everything to old values. So, there is
- 4:57our camera drag module.
- 5:00So, I was going to show you guys what
- 5:02the controls looked like on Xbox or a
- 5:05gamepad. So, here we are. Here you guys
- 5:08see a little preview of what everything
- 5:09looks like, but basically, we can use
- 5:11the D-pad to zoom in and out and also we
- 5:14can move our camera with the left
- 5:17joystick.
- 5:19And then if we wanted to actually select
- 5:21something, then we'd use the virtual
- 5:22cursor and also the camera moves with
- 5:25that as well. And then we would
- 5:27hold down the right trigger to
- 5:30activate the buttons and buy new ones if
- 5:32we wanted to.
- 5:34[Music]
- 5:36So, now let's get into the actual
- 5:38buttons we have here. So, how are these
- 5:40being handled? Well, for this system, I
- 5:43use a custom click detector module
- 5:46instead of regular click detectors and
- 5:48why I do this is because this module has
- 5:51more events that the regular click
- 5:53detector does not. For example, mouse
- 5:55down and mouse up. So, if I were to hold
- 5:58down my mouse over the button, then it
- 5:59works and if I release it, then that
- 6:02works as well.
- 6:03And it's very easy to use, too. So, if I
- 6:06open up my skill tree client script and
- 6:08go down to here where we handle it, we
- 6:10just loop through all the nodes and then
- 6:14find the base and then make a new
- 6:16detector and then just make it so when
- 6:20we have our mouse entering the base,
- 6:23then it works. Mouse leave, mouse down
- 6:25and then mouse up and then we tween the
- 6:29button.
- 6:30And yes, these buttons are models. So,
- 6:32how we are doing that, I know there's
- 6:34modules for this, but we're doing it the
- 6:36hard way. We have this tween scale
- 6:38function where it takes in the model and
- 6:40the target scale and uses run service
- 6:43along with tween service to smoothly
- 6:46scale the button. So, there's that
- 6:48function here.
- 6:51But while I was testing this on mobile,
- 6:53it was kind of hard to actually click
- 6:56the buttons because a lot of times it
- 6:58wasn't registering, so I didn't know if
- 6:59it was with the module or something like
- 7:01that. So, to fix that,
- 7:05that is where this part of the code
- 7:08comes into play.
- 7:09So, basically, what this get part from
- 7:11touch function is doing is given a
- 7:14screen position or touch position, it
- 7:16tells us what 3D object the player is
- 7:19actually touching.
- 7:20So, touch position is 2D, so we send it
- 7:24here into screen point to ray, so we
- 7:26convert that screen point into a ray
- 7:29that shoots out of the camera. So, then
- 7:31we have this unit ray variable. And then
- 7:33we use ray casting to actually get the
- 7:35part. So, here we shoot a ray from the
- 7:38unit ray's origin and then send it in
- 7:40the direction and then we multiply it
- 7:42times 1,000, so we actually hit it,
- 7:44which 1,000's probably overkill, but it
- 7:47works and
- 7:49then we send in our parameters, which
- 7:51don't think I need respect can collide
- 7:53because I was just testing with that.
- 7:55But basically, here we have it set to
- 7:57ray cast filter type include, so it
- 7:59includes all of these nodes and so we
- 8:02get that ray cast and return the result.
- 8:05And then down here, when there is
- 8:08movement or touch on the screen, then we
- 8:11get the result from get part from touch
- 8:14and check if there actually is result
- 8:16and there's an instance to it, then we
- 8:18find that node and make sure the node
- 8:20exists and if it does, then reset active
- 8:24node to our touch node to that node,
- 8:26tween the node and then send a packet,
- 8:29which I'll go over here in just a
- 8:30second. And then touch ended just
- 8:32handles that with tween scale and then
- 8:35set active touch node back to nil.
- 8:38So, now let's follow this little
- 8:39pipeline we have here. In both of these
- 8:41parts of the code, we are sending the
- 8:44skill tree info packet to the server and
- 8:47we are sending the node name. So, on the
- 8:50server, we pick that up and here's the
- 8:53skill name.
- 8:54So, we are just checking if the player
- 8:56already owns that skill, then we just
- 8:59warn already owned and return. And if
- 9:02they don't already have it owned, then
- 9:04we check if they have the prerequisites.
- 9:08And so, that means it checks to see if
- 9:10we have the other buttons before that
- 9:12unlocked. And how we do that is we have
- 9:14a module called skill tree data and this
- 9:17is probably isn't set up in the best
- 9:19way, but it gets the job done.
- 9:21Basically, these are all of the buttons
- 9:24and they are titled with their names and
- 9:26they each have an ID, what branch
- 9:28they're part of, which is the color, and
- 9:31the prerequisites, which is a table that
- 9:33points to the ID of what you need to
- 9:35have already owned. And then we have the
- 9:38cost. So, if I wanted to have defense or
- 9:40try and buy defense, then I would have
- 9:43to have jump height and walk speed
- 9:44already unlocked. So, that's pretty
- 9:46self-explanatory.
- 9:48So, it just checks that and so, if we
- 9:50don't have those already owned, then
- 9:53once again, we warn and return, so
- 9:55everything down here doesn't run. But
- 9:57then, we check in the data manager,
- 9:59which has more to do with
- 10:02data stores, which I will also get into.
- 10:04So, sit tight for that. So, we're just
- 10:06checking if we have enough skill points
- 10:08for that for the cost. And if we do,
- 10:11then we manage the skills, which is
- 10:13basically add or subtract.
- 10:16Or no, sorry, sorry. That's this. Okay,
- 10:18so manage skills, we send in the player
- 10:20and the skill name. So, now we just make
- 10:22it so the player owns the skill and
- 10:24manage skill points is where we actually
- 10:26take away the cost or the number of
- 10:29skill points away from the player. And
- 10:31then, we fire another packet back to the
- 10:33client.
- 10:35And so then, what happens when we return
- 10:37back to the client is down here,
- 10:40we get the actual node model
- 10:44using the skill name that we sent. We
- 10:46get the base, and then we set the color
- 10:48of the base. We then get a little
- 10:50sparkle particle that plays for a nice
- 10:52little effect. And then,
- 10:55remember the next node attribute, we get
- 10:58the next node attribute inside of the
- 11:00node and then find the next node
- 11:02physical model, and we set that so that
- 11:05it's visible and we can see it. Now,
- 11:07down here, this is just another little
- 11:09effect to show that we own the button.
- 11:11It's a little shine effect, which I
- 11:13should probably put back up here the
- 11:15sparkles, but you know,
- 11:17it's right there. And then,
- 11:19we set the surface GUI
- 11:22GUI. All right. Surface GUI
- 11:25of that next node equal to true so we
- 11:27can also see that. And then, get the
- 11:30connector attribute, get that actual
- 11:32connector, and set the beams enabled
- 11:35property of that connector equal to
- 11:37true.
- 11:38And so, if you guys want a little bit
- 11:40more information on the connector parts,
- 11:42well, here we have connector one and
- 11:44two, and basically, it's just a part and
- 11:48these two attachments are in it
- 11:50is what basically controls the beam. So,
- 11:53the first one or well,
- 11:55this should be number one, but
- 11:57basically, the one attachment is in the
- 12:00middle of the one point or one base, and
- 12:03then the other attachment is in the
- 12:04center of the other one. And here's our
- 12:06beam that just connects them. So, pretty
- 12:08simple.
- 12:10So, now let's get more into data saving
- 12:13and stuff like that. So, for this, I am
- 12:16obviously obviously using profile store
- 12:19because it's just easy and literally has
- 12:21everything for you already built into
- 12:23it. So, let's take a look at stats.
- 12:25Here, the stats are just setting up the
- 12:28skill points, the skill tree folder in
- 12:30the player, and then also a folder for
- 12:33each of the colors. And then,
- 12:36we are sending a packet, which I will
- 12:38also explain. But first, we're waiting 1
- 12:40second to make sure everything is loaded
- 12:42because if I didn't have this here, it
- 12:44was breaking. So, then the simple task
- 12:46that await worked. And so after we send
- 12:49that packet, we are looping through all
- 12:51of the owned skills in the player skill
- 12:54tree and making strings and setting the
- 12:58parent of that string to the color, the
- 13:01correct color folder.
- 13:03So, going ahead and looking at the
- 13:06client, looking at skill tree joint
- 13:08packet, this just makes it so everything
- 13:11is set up when the player joins the
- 13:13game. So, we send all of the player's
- 13:16own skills back over here. And then, we
- 13:19convert this own skills table or list
- 13:22into a dictionary
- 13:24because later on, we will loop through
- 13:26everything, but checking a list is can
- 13:29be slow, but it would be more slow if we
- 13:32had more skills. So, we're just setting
- 13:33up everything into a dictionary so
- 13:35everything is faster. And if you've
- 13:37watched my other videos, you know that
- 13:40direct lookup is big O of one.
- 13:43And so then down here, it's basically
- 13:45doing exactly what I explained before,
- 13:48where we find the node, find the base
- 13:49and the ring, set the base color and the
- 13:51transparency, add the shine particle,
- 13:55and make it so we can see the surface
- 13:56GUI. And then, when we come down here,
- 14:00this is where we enable connections and
- 14:02reveal the next skill. So, we loop
- 14:04again. I know loop, I know I'm
- 14:06contradicting myself, but just give me a
- 14:08minute, all right? So, we're looping
- 14:09through all of the skills in the owned
- 14:12lookup.
- 14:13And so here,
- 14:15we are getting the node, and then the
- 14:18next node
- 14:20attribute and also the connector name
- 14:22attribute. And then, we come down here
- 14:24and get that next node and also get the
- 14:26connector and set that equal to true.
- 14:29And then finally, we come down here and
- 14:32look up the next node and get that next
- 14:36node base and a ring, set the
- 14:38transparency so we can see it, and also
- 14:41set the surface GUI. So, why are we
- 14:43doing this? Well,
- 14:45if we just spawned or made everything
- 14:47visible that we owned, then how are we
- 14:50supposed to keep expanding the skill
- 14:52tree if we don't have everything? So,
- 14:53that's why down here, we get the next
- 14:56node and the connector, so then we can
- 14:58see that and be able to keep growing the
- 15:01skill tree if we don't have it fully
- 15:02unlocked.
- 15:04And so that is also why we aren't
- 15:05setting the color of the base because we
- 15:07don't own it. So, you know, there we go.
- 15:10So yeah, guys, that is pretty much my
- 15:12little skill tree project here. I'm now
- 15:14going to go in and basically just play
- 15:17around with it more so you guys can see
- 15:19it. So,
- 15:20again, there's the camera drag with the
- 15:22smooth movement and scrolling. And as
- 15:25you can see, the shine particle
- 15:28works just fine and is very cool. And
- 15:31then as you can see, like I just
- 15:33explained, it shows the connector and
- 15:36the next node so then we can keep
- 15:39growing the skill tree.
- 15:40And I believe I have enough points, so I
- 15:42can just check that again. All right, I
- 15:44have 19. So, if I wanted to buy a new
- 15:47node,
- 15:50and there we go.
- 15:53If I come over here,
- 15:56and I can buy
- 15:57the rest of the nodes
- 16:00just like that. There we go.
- 16:03And I'm a little unsure on why these
- 16:06aren't working with the particles, but
- 16:08you know, this system isn't completely
- 16:09done because
- 16:11these buttons don't actually do anything
- 16:13when you buy them cuz this isn't an
- 16:15actual game. This was just for
- 16:17a little
- 16:19practice and fun. So,
- 16:22these don't actually give you anything,
- 16:24but if it were an actual game, it
- 16:25wouldn't be hard to do that. But there
- 16:27we go. This is the full skill tree
- 16:30done.
- 16:33Okay, guys. So, I just took a little
- 16:36break to take a look at my code again,
- 16:38and I think I figured out why the shine
- 16:41wasn't working.
- 16:43And it's because it was only not working
- 16:46on the last button of the branch. So,
- 16:50if I were to buy the green one down
- 16:53here,
- 16:55that would start working. But if I were
- 16:57to buy this, then that wouldn't work.
- 17:00And that's because I would clone the
- 17:02shine after I would check for next node.
- 17:05And so since
- 17:07the last button in the tree doesn't have
- 17:09a next node or doesn't point to a next
- 17:12node, then it won't run. So, all I would
- 17:14have to do
- 17:16is
- 17:17[Music]
- 17:18copy this
- 17:20and put it
- 17:22before that. So, let's go ahead and try
- 17:24that again.
- 17:26If I were to buy that,
- 17:28that would work.
- 17:30That would work.
- 17:33And that would work. There we go.
- 17:35Just like that. So, let me go ahead and
- 17:37fill out the entire thing now.
- 17:39There is the entire skill tree once
- 17:41again.
- 17:43[Music]
- 17:45And so yeah, guys, this was today's
- 17:47video. If you guys did learn something
- 17:49from this video or you guys enjoyed this
- 17:50video, please hit the like button and
- 17:53subscribe button. I will see you guys in
- 17:55the next video, and peace.
About this transcript
This page contains the full transcript of How I Designed a Scalable Skill Tree System | Roblox Studio by Stewiepfing, generated from the public captions YouTube serves with the video. The transcript has 3,087 words across 462 segments, with the original timestamps preserved so you can click any line to jump to that moment in the embedded player.
What you can do with it
Use the transcript to take notes, quote the speaker, build a study guide, generate a summary with ChatGPT or Claude via the YouTube Summary tool, or export it as a timed subtitle file with YouTube to SRT. You can also re-open it in the transcriber to choose a caption track available on the video.
Free YouTube transcript tool
YouTube2Text is a free YouTube transcript generator — no signup, no daily limit. Paste any YouTube link and get the full transcript instantly, with timestamps, click-to-jump, caption language selection, AI prompts for ChatGPT, Claude, and Gemini, and exports to TXT, SRT, VTT, or Markdown.