Over the last few months, our community has come up with a long list of cool tricks to get larger Rosebud projects to work better.
Whether that be writing detailed comments for Rosie in your code, sticking only to Diff-Mode for entire projects, or even linking Rosebud projects within Rosebud projects.
This is a quick tutorial on how to make use of one of the most reliable techniques, moving parts of the code that won't be modified much outside of the Code Tab and into script assets
that will live in the Asset Tab. This approach can be intimidating at first, but it doesn't require much familiarity with code and can make prompting multiple times easier when your projects start reaching 1000+ line sizes!
This shouldn't take more than a few minutes to skim through.
If you have any questions about following these steps, join our Discord and let us know how we can help make your experience even better!
Step 1: Add a Script Loader to your code
The first step is to ask Rosie to add the following script loader to your project.
You can simply copy and paste it:
function loadScript(url) {
return new Promise((resolve, reject) => {
// Check if the script is already loaded
if (document.querySelector(`script[src="${url}"]`)) {
resolve();
return;
}
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
script.onload = () => resolve();
script.onerror = () => reject(new Error('Script loading failed for ' + url));
document.head.appendChild(script);
});
}
You can also ask Rosie to create one from scratch, but showing her this already working one will help her succeed more reliably.
To clarify what I mean by "script," a script is simply a single file that has code that is able to run. Your game code in the Code Tab is also a script. Our goal with this tutorial is to add a script loader
to our game that can load other scripts. That way, we can add features to our game without filling up our Code Tab!
A good example of this is the AI Character template. If you remix it and look at its code, the code for the chat interface isn't in the Code Tab. So where is it coming from? It's coming from a script that we're loading with the script loader (see line 119 of the AI Character project code).
Step 2: Ensure your project is broken into separate pieces
The next step is for us to make sure our project is broken into separate pieces.
This is called modularization
, and it's super important if we want to move certain pieces of our code outside of the Code Tab.
To give an analogy, imagine your room at home had too much stuff, and you wanted to move some of it to the basement. What if the biggest thing in your room, the thing you want to move most, was an unused desk?
If that desk was too big to fit through the door, had a bunch of books on it, and a bunch of wires tangles around it, you wouldn't just forcibly pull it out of your room. That would cause damage and leave you in a worse spot.
You would instead first get the books off and put them in their own pile, untangle + separate the wires, and then disassemble the table to make it easier to bring to the basement.
This is exactly what we need to do with our project before moving parts of it out.
Pick a small part of your game that you know you won't be changing much for the rest of the project (e.g. the user interface). Ask Rosie to make that part of the code into a modular class
. In programming, think of a "class" as a building block of your project.
Use a prompt similar to the following (make sure what you chose to turn into a modular class matches your own project):
Please add the following script loader to the project.
function loadScript(url) {
return new Promise((resolve, reject) => {
// Check if the script is already loaded
if (document.querySelector(`script[src="${url}"]`)) {
resolve();
return;
}
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
script.onload = () => resolve();
script.onerror = () => reject(new Error('Script loading failed for ' + url));
document.head.appendChild(script);
});
}
Please then turn the user interface into a modular class that I can then move myself to an external script. I'm going to load the script with our new script loader. Please make sure it's easy for me to copy and paste the new modular class from your response.
Rosie should then alter your project code to have the part of the code you specified to be a modular class.
For example, if you asked Rosie to turn the UI into a class, it should look something like this now:
class UIScene extends Phaser.Scene {
constructor() {
super('UIScene');
this.score = 0;
}
create() {
this.scoreText = this.add.text(10, 10, 'Score: 0', { fontSize: '32px', fill: '#fff' });
this.button = this.add.text(400, 300, 'Click me!', { fontSize: '32px', fill: '#0f0' })
.setOrigin(0.5)
.setInteractive({ useHandCursor: true })
.on('pointerdown', () => this.incrementScore());
}
incrementScore() {
this.score += 1;
this.scoreText.setText('Score: ' + this.score);
}
}
Step 3: Move the code to a script file
Next, we need to create a new file, copy the modular code from Step 2, and paste it into the new file.
Please head to your desktop and create a file called {something}_script.js
.
Make sure to replace the {something}
with whatever the feature you modularized in Step 2 is.
Ensure that the file you create has .js
at the end. If you don't know how to do this, first just create a regular text file, and then, when it's already there, change the ending from .txt
, or whatever it is, to .js
.
Next, please paste the Code from Step 2 into the file. You can now delete the Step 2 code from the Code Tab. We're going to load it from the script, so it no longer needs to be in the Code Tab!
Step 4: Uploading and using our new script file
Now, we can upload that script to the asset tab!
Please head over to the asset tab and click the Upload Asset
button. Then, select the new file you created.
In the chat tab, use the '@' sign to select the asset, and then tell Rosie to load it as a script using the script loader. I would strongly recommend that you directly show Rosie the code inside the script in that same prompt, as she isn't able to open the script and see it for herself. Here is an example prompt:
I moved the modular user interface class to an external script. Here is the script @{select script from asset list}.
Here is what's inside for reference:
class UIScene extends Phaser.Scene {
constructor() {
super('UIScene');
this.score = 0;
}
create() {
this.scoreText = this.add.text(10, 10, 'Score: 0', { fontSize: '32px', fill: '#fff' });
this.button = this.add.text(400, 300, 'Click me!', { fontSize: '32px', fill: '#0f0' })
.setOrigin(0.5)
.setInteractive({ useHandCursor: true })
.on('pointerdown', () => this.incrementScore());
}
incrementScore() {
this.score += 1;
this.scoreText.setText('Score: ' + this.score);
}
}
After that, your project should work with the feature you chose in Step 2, even though it isn't in the Code Tab.
Your project should now be more lightweight, making it easier to send prompts, but still have the same features!