| Crates.io | vake |
| lib.rs | vake |
| version | 1.0.2 |
| created_at | 2025-06-14 20:15:05.098499+00 |
| updated_at | 2025-06-19 15:24:51.628577+00 |
| description | Custom build tool for the In Silico project |
| homepage | |
| repository | |
| max_upload_size | |
| id | 1712635 |
| size | 186,762 |
Vake is an unopinionated build system written in Rust to build and sync projects to Roblox Studio. It allows you to organize your Roblox projects in the file system without being confined to a specific organizational ideology. Project structures are defined in a vakefile, and can be used to describe any hierarchy model in Roblox Studio.
Install the plugin on Roblox, use the attached Lua file, or build it yourself using MoonScript. If you are building the plugin yourself, use moonc plugin.moon, which will build plugin.lua.
Install the CLI application by building it yourself by running cargo build --release in the project directory, using the executable provided under Releases, or through crates.io using cargo install vake.
Once the plugin and CLI are installed, running vake in your project directory and clicking on the plugin in Roblox Studio to enable it will allow the changes in your editor to be synced with the Roblox Studio instance. In order to work properly, the plugin must be granted permission to make HTTP requests and create and manage scripts.
Restarting the plugin will remove any scripts created by vake until they are recreated when connected to the server. Beware that any inserted children of created folders/scripts will be removed when large changes are synced or the plugin is restarted.
The configuration file for your vake project will be automatically detected if it has the name vakefile, .vake, or .vakefile. Vake will automatically look for changes in the project directory and will reflect changes in Roblox Studio according to the specified configuration. Changes to the configuration file are not currently hot-reloaded, so any changes require the CLI to be restarted.
To start a new project, run vake in an uninitialized directory to create a vakefile with the default configuration. The contents of the configuration file describe a Recipe, which contains 3 types of configuration:
Options provide metadata about how the project is going to be constructed. Options are always prefixed with a : and defined with the :option = value syntax.
:active_directory = "src" # Path specifying the working directory
:case_type = "pascal" # Specifies the case of script names in Roblox (pascal, camel, snake, kebab)
:case_abbreviations = false # Preserve all-caps file names to support abbreviations
:case_exceptions = [ "", "" ] # Files to skip case conversion on
:entry_name = "main.lua" # The entry file for the project, currently has no effect
:preprocess_text = true # `.txt` files are preprocessed to return strings
:preprocess_pretty = false # Stylistic changes to preprocessed files
:cc = "" # Currently unused, will eventually be used to compile files of arbitrary type
:cflags = "" # Currently unused, will eventually be used to specify flags to the compiler
Associations relate specific directories to a specific instance type. This allows certain directories to create Local, Module, and Server script instances according to the specification. Associations use a :: to separate the directory from the script type.
client :: LocalScript
modules :: ModuleScript
server :: ServerScript # This is optional, all scripts are ServerScripts by default
Entries describe how file system directories will be mapped to the Roblox explorer tree. Entries use an -> to separate the directory from the explorer path. Special separators are used in entry paths describing the Roblox explorer hierarchy which allow precise control over how the directories are managed. Roblox paths always begin with the name of a service (Workspace, ServerScriptService, StarterPlayer, ...etc) and are dilineated with ., :, or ! with each separator having a different action:
. operator simply indexes the child element of the lefthand side, where Parent.Child is equivalent to Parent:FindFirstChild("Child").: operator waits for the child element asynchronously to allow dependency chains to be resolved, where Parent:Child is equivalent to Parent:WaitForChild("Child"). The : operator is non-blocking and works even with bad ordering.! operator simply creates the child if it does not exist (in the form of a Folder), and then indexes it.An example entry where all files in the shaders directory are placed into a folder under a pre-existing Client script titled Shaders in StarterPlayerScripts:
shaders -> StarterPlayer.StarterPlayerScripts:Client!Shaders
Both associations and entries use special Recipe Paths to describe the file location of a specific folder in the configuration. A recipe path is delineated with either a . or a /, and are always descendants of the :active_directory. An example of defining an association and entry for a deeply nested folder:
:active_directory = "src"
...
very.specific.folder :: LocalScript # Alternatively, very/specific/folder
...
very.specific.folder -> StarterPlayer.StarterPlayerScripts # Alternatively, very/specific/folder
Note: To specify the current directory, simply use
.or/as the path.
Here is an example recipe that describes a project with a specific folder structure that utilizes a variety of options:
# Options
:active_directory = "src"
:entry_name = "game.luau"
# Associations
client :: LocalScript
client.shaders :: ModuleScript
client.modules :: ModuleScript
# Entries
/ -> ServerScriptService
server -> ServerScriptService:Main
client -> StarterPlayer.StarterPlayerScripts
client.modules -> StarterPlayer.StarterPlayerScripts:Client!Modules
client.shaders -> StarterPlayer.StarterPlayerScripts:Client!Shaders
Vake is currently still in development, so Pull Requests are welcome to improve and expand the project. Any encountered issues or feature requests can be reported on the Issues page of the repository.
Keep in mind that this project is still being actively developed, so issues are bound to occur at any point. Vake is also trying to become more flexible, so any input in regards to making adoption easier are welcome. Feel free to reach out in the Roblox Open Source Community thread.