From 2a4ca21050a1a5aa17a5368cbae450869d63d40f Mon Sep 17 00:00:00 2001 From: Lucien Greathouse Date: Fri, 7 Jun 2019 18:29:09 -0700 Subject: [PATCH] Substantial documentation improvements --- docs/creating-a-place.md | 68 ---------------- docs/extra.css | 10 +++ docs/guide/existing-game.md | 0 docs/{ => guide}/installation.md | 5 +- docs/{ => guide}/migrating-to-epiphany.md | 0 docs/guide/new-game.md | 90 ++++++++++++++++++++++ docs/images/connection-dialog.png | Bin 0 -> 13716 bytes docs/{ => reference}/project-format.md | 69 ++++++++++++++--- docs/{ => reference}/sync-details.md | 6 +- docs/rojo-alternatives.md | 23 ++++++ docs/why-rojo.md | 43 +++++++---- mkdocs.yml | 14 ++-- 12 files changed, 221 insertions(+), 107 deletions(-) delete mode 100644 docs/creating-a-place.md create mode 100644 docs/guide/existing-game.md rename docs/{ => guide}/installation.md (92%) rename docs/{ => guide}/migrating-to-epiphany.md (100%) create mode 100644 docs/guide/new-game.md create mode 100644 docs/images/connection-dialog.png rename docs/{ => reference}/project-format.md (58%) rename docs/{ => reference}/sync-details.md (94%) create mode 100644 docs/rojo-alternatives.md diff --git a/docs/creating-a-place.md b/docs/creating-a-place.md deleted file mode 100644 index d20f8ffd..00000000 --- a/docs/creating-a-place.md +++ /dev/null @@ -1,68 +0,0 @@ -[TOC] - -## Creating the Rojo Project - -To use Rojo to build a place, you'll need to create a new project file, which tells Rojo how your project is structured on-disk and in Roblox. - -Create a new folder, then run `rojo init` inside that folder to initialize an empty project. - -```sh -mkdir my-new-project -cd my-new-project - -rojo init -``` - -Rojo will make a small project file in your directory, named `default.project.json`. It'll make sure that any code in the directory `src` will get put into `ReplicatedStorage.Source`. - -Speaking of, let's make sure we create a directory named `src`, and maybe a Lua file inside of it: - -```sh -mkdir src -echo 'print("Hello, world!")' > src/hello.lua -``` - -## Building Your Place -Now that we have a project, one thing we can do is build a Roblox place file for our project. This is a great way to get started with a project quickly with no fuss. - -All we have to do is call `rojo build`: - -```sh -rojo build -o MyNewProject.rbxlx -``` - -If you open `MyNewProject.rbxlx` in Roblox Studio now, you should see a `Folder` containing a `ModuleScript` under `ReplicatedStorage`! - -!!! info - To generate a binary place file instead, use `rbxl`. Note that support for binary model/place files (`rbxm` and `rbxl`) is very limited in Rojo presently. - -## Live-Syncing into Studio -Building a place file is great for the initial build, but for actively working on your place, you'll want something quicker. - -In Roblox Studio, make sure the Rojo plugin is installed. If you need it, check out [the installation guide](installation) to learn how to install it. - -To expose your project to the plugin, you'll need to _serve_ it from the command line: - -```sh -rojo serve -``` - -This will start up a web server that tells Roblox Studio what instances are in your project and sends notifications if any of them change. - -Note the port number, then switch into Roblox Studio and press the Rojo **Connect** button in the plugins tab. Type in the port number, if necessary, and press **Start**. - -If everything went well, you should now be able to change files in the `src` directory and watch them sync into Roblox Studio in real time! - -## Uploading Your Place -Aimed at teams that want serious levels of automation, Rojo can upload places to Roblox.com automatically. - -You'll need an existing place on Roblox.com as well as the `.ROBLOSECURITY` cookie of an account that has write access to that place. - -!!! warning - It's recommended that you set up a Roblox account dedicated to deploying your place instead of your personal account in case your security cookie is compromised. - -Generating and uploading your place file is as simple as: - -```sh -rojo upload --asset_id [PLACE ID] --cookie "[SECURITY COOKIE]" -``` \ No newline at end of file diff --git a/docs/extra.css b/docs/extra.css index 020a7103..ed31fbc9 100644 --- a/docs/extra.css +++ b/docs/extra.css @@ -1,3 +1,13 @@ .md-typeset__table { width: 100%; +} + +.feature-image img { + border: 1px solid rgba(0, 0, 0, 0.2); + box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.2); +} + +.codehilite { + border: 1px solid rgba(0, 0, 0, 0.2); + box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.2); } \ No newline at end of file diff --git a/docs/guide/existing-game.md b/docs/guide/existing-game.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/installation.md b/docs/guide/installation.md similarity index 92% rename from docs/installation.md rename to docs/guide/installation.md index 728c8dfd..b56f31c8 100644 --- a/docs/installation.md +++ b/docs/guide/installation.md @@ -1,7 +1,8 @@ +This is this installation guide for Rojo **0.5.x**. + [TOC] ## Overview - Rojo has two components: * The command line interface (CLI) @@ -35,7 +36,7 @@ The Rojo Roblox Studio plugin is available from Rojo's [GitHub Releases page](ht Download the attached `rbxm` file and put it into your Roblox Studio plugins folder. You can find that folder by pressing **Plugins Folder** from your Plugins toolbar in Roblox Studio: -!['Plugins Folder' button in Roblox Studio](images/plugins-folder-in-studio.png) +!['Plugins Folder' button in Roblox Studio](../images/plugins-folder-in-studio.png) {: align="center" } ### Installing from Roblox.com diff --git a/docs/migrating-to-epiphany.md b/docs/guide/migrating-to-epiphany.md similarity index 100% rename from docs/migrating-to-epiphany.md rename to docs/guide/migrating-to-epiphany.md diff --git a/docs/guide/new-game.md b/docs/guide/new-game.md new file mode 100644 index 00000000..7a3f46ca --- /dev/null +++ b/docs/guide/new-game.md @@ -0,0 +1,90 @@ +[TOC] + +## Creating the Rojo Project +To use Rojo to build a game, you'll need to create a new project file, which tells Rojo how to turn your files into a Roblox place. + +First, create a new folder to contain the files for your game and open up a new terminal inside of it, like cmd.exe or Bash. + +It's convenient to make the folder from the command line: + +```sh +mkdir my-new-project +cd my-new-project +``` + +Inside the folder, initialize a new Rojo project: + +```sh +rojo init +``` + +Rojo will make a small project file in your directory, named `default.project.json`. It matches the "Baseplate" template from Roblox Studio, except that it'll take any files you put in a folder called `src` and put it into `ReplicatedStorage.Source`. + +Speaking of files, make sure to create a directory named `src` in this folder, or Rojo will be upset about missing files! + +```sh +mkdir src +``` + +Let's also add a Lua file, `hello.lua` to the `src` folder, so that we can make this project our own. + +```sh +echo 'return "Hello, Rojo!"' > src/hello.lua +``` + +## Building Your Place +Now that we have a project, one thing we can do is build a Roblox place file for our project. This is a great way to get started with a project quickly with no fuss. + +All we have to do is call `rojo build`: + +```sh +rojo build -o MyNewProject.rbxlx +``` + +If you open `MyNewProject.rbxlx` in Roblox Studio now, you should see a `Folder` containing a `ModuleScript` under `ReplicatedStorage`! + +!!! info + To generate a binary place file instead, use `rbxl`. Note that support for binary model/place files (`rbxm` and `rbxl`) is very limited in Rojo presently. + +## Live-Syncing into Studio +Building a place file is great for starting to work on a game, but for active iteration, you'll want something faster. + +In Roblox Studio, make sure the Rojo plugin is installed. If you need it, check out [the installation guide](installation) to learn how to install it. + +To expose your project to the plugin, you'll need to start a new **live sync session** from the command line: + +```sh +rojo serve +``` + +You should see output like this in your terminal: + +```sh +$ rojo serve +Rojo server listening on port 34872 +``` + +Switch into Roblox Studio and press the **Connect** button on the Rojo plugin toolbar. A dialog should appear: + +![Rojo plugin connection dialog](../images/connection-dialog.png) +{: class="feature-image" align="center" } + +If the port number doesn't match the output from the command line, change it, and then press **Connect**. + +If all went well, you should now be able to change files in the `src` directory and watch them sync into Roblox Studio in real time! + +## Uploading Your Place +Aimed at teams that want serious levels of automation, Rojo can upload places to Roblox.com automatically. + +You'll need an existing game on Roblox.com as well as the `.ROBLOSECURITY` cookie of an account that has write access to that game. + +!!! warning + It's recommended that you set up a Roblox account dedicated to deploying your game instead of your personal account in case your security cookie is compromised. + +Generating and publishing your game is as simple as: + +```sh +rojo upload --asset_id [PLACE ID] --cookie "[SECURITY COOKIE]" +``` + +An example project is available on GitHub that deploys to Roblox.com from GitHub and Travis-CI automatically: [https://github.com/LPGhatguy/roads](https://github.com/LPGhatguy/roads) \ No newline at end of file diff --git a/docs/images/connection-dialog.png b/docs/images/connection-dialog.png new file mode 100644 index 0000000000000000000000000000000000000000..5a3d5f29def79d087cc0d9d58e28e2f8d7f6eafd GIT binary patch literal 13716 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