Volt - An efficient & powerful game framework

VoltLogo Volt

:floppy_disk: Download | v1.1.0 | GitHub :file_folder:


:wave: Introduction

Welcome to Volt, an extremely powerful game framework. You may have heard of other frameworks such as AGF or Knit which are both very popular and for good reason. They’re great frameworks. That said, Volt offers itself as an alternative. While AGF & Knit focus on the server-client boundary side of Roblox, Volt focuses on organization and control flow while still offering user-friendly solutions for handling the client-server boundary.


:arrow_double_up: Advantages

:paperclip: Lightweight

Volt is lightweight and will have little to no noticeable impact on your game’s performance. It’s compact and requires 5 essential modules to run properly only spanning ~200 lines of code with the potential for even further future optimization.

:open_file_folder: Powerful Directory & Import System

Various parts of Volt use an intuitive directory system. For example, Volt comes equipped with an import function for importing modules. Let’s say you had a module in ReplicatedStorage → SomeFolder → MyModule. Using Volt all you have to type to import it is

local myModule = Volt.import('SomeFolder/MyModule')

Furthermore, when importing in Volt there’s a neat little priority system that will check multiple directories if Volt fails to find what you’re trying to import.

:arrows_counterclockwise: Control Flow

As stated in the introduction Volt gives users the ability to manipulate the control flow of their game. What this means is that you have the power to control what order your scripts run in. The way Roblox executes your scripts is entirely random meaning something might run before something else you expect to run first. This problem isn’t seen with Volt as it uses scripts known as executables where you define their control flow.

:cloud_with_lightning: Client & Server Executables

Executables are simply module scripts with a few special attributes. Think of them like either a server script or local script. If you’re familiar with AGF & Knit executables can also be seen as incorporating both services and controllers. Executables can run synchronously or asynchronously and are ran based on how they are passed into Volt. This is how control flow is manipulated.


:blue_book: Documentation


:electric_plug: Plugin

To simplify the creation of executables a plugin exists and is maintained. For more information view here.
https://www.roblox.com/library/6899608114/Volt-Plugin


:play_or_pause_button: Demo Place

Feel free to check out this Volt demo place. It showcases a few executables working side-by-side to handle UI, parts, a money system, and server/client interaction. The place is uncopylocked so feel free to take a look at the code inside to learn how it uses Volt.
https://www.roblox.com/games/6900493438/Volt-Demo

52 Likes

This is a rather interesting framework layout- I’ll definitely be taking a look into this.

1 Like

Forgive me for not knowing much but what is a framework? What does volt do?

3 Likes

The purpose of Volt is to simplify the game development workflow as well as provide more power to game developers. Many people will create their own frameworks specific to their games but there are a few public ones that exist such as Volt, Aero Game Framework, and Knit. They each have a different feature-set but aim to make scripting a large-scale game easier.

Volt in its current version does this in a few ways. Firstly through imports. Volt has a really nice import function that allows you to require() modules in a seamless manner. Secondly through executables & bridges. Bridges act as a wrapper for and remove the need for RemoteEvents and RemoteFunctions. Executables use these bridges to run code similar to server & local scripts. The key difference is that you have control over how these executables run. You define which executes first, second, third, etc. On top of this executables can communicate with each other. Right now in Roblox if you had two server scripts and wanted them to talk to each other whether it be by calling a function or passing a value you have to create a BindableEvent or BindableFunction. This is tedious work that executables solve by making themselves public to other executables.

Like @nodoubtjordan mentioned it’s interesting in that it’s unique. Volt doesn’t attempt to completely replace server & local scripts but rather provides a more powerful alternative. This is something I personally haven’t seen anywhere else and I really don’t know how it will pan out. Maybe the idea is too strange for people to become accustomed to or maybe it really is as good as I think.

Regardless, try it out and try to familiarize yourself with it. Feel free to give me any feedback!

6 Likes

I’d say interesting, but the documentation is very lacking. Check out AGF & Knit documentaries for inspiration. Also, you should add a few libraries RoStrap because some of them could be useful.

1 Like

Yeah this was a fear of mine when I posted this. I tried to go as in-detail as possible and thought the crash course video might help but there’s really a lot to unpack. I have little experience with GitHub pages but have been doing research and will hopefully get a site up and running built with docsify for more in-depth documentation. As for RoStrap I’ll definitely include a surplus of libraries from there in the next update. Thanks for the feedback!

2 Likes

You should use RunService:IsClient() for checking if its running on the client instead of doing this:
image

3 Likes

Yes, but why reinvent the wheel when there is literally an official method to do this? (and likely more reliable if one day Roblox devices Players.LocalPlayer should return a non-falsey value on the server for some reason)

3 Likes

I was honestly unaware of the IsClient method but I think I’ll implement it as it’s a bit cleaner in terms of readability and this is meant to be an open source project.

As for my script editor theme glad you like it

Font is FiraCode

3 Likes
local Volt = require(game.ReplicatedStorage.Volt)
local InstanceBuilder = Volt.import('Libraries/InstanceBuilder')

why use forward slashes?

Why not? They are used to require and import folders almost everywhere

3 Likes

For readability and functionality purposes. Using a forward slash based directory system looks clean and inherits the style of Unix & Mac file systems. Is there a different way you believe is more user-friendly?

3 Likes

Volt | v1.0.1

:floppy_disk: Download

:new: What’s New

  • Updated and far more in-depth documentation using GitHub Pages
    • Thanks to @OminousVibes0 for pointing out the current documentation was lackluster this should seriously help
  • Libraries now require a name property
  • Libraries can now be directly referenced from Volt.Libraries
    • However, importing them is still recommended as direct references may break functionality
  • Libraries are now injected into each other
  • Added a variety of new built-in libraries
    • Maid by Quenty
    • Array by Validark
    • Spring by fractality
    • Table by Quenty
    • Signal by Quenty
4 Likes

I guess it’s a stylistic choice, but seems against the Lua standard of using dots. Personally, even if the resources taken up for string manipulation are negligible, I’d go with dots. I know Roblox’s intellisense is garbage, but they might fix it in the future.

Volt Plugin

Information

Quickly create executables with this plugin. Executables can be tedious to create and the plugin simplifies the process. Type your executable name in the UI and hit Create. You’ll get yourself a new folder with two generated client & server executables containing base code to work off of. They also will automatically append .Client and .Server to follow Volt naming conventions.

image

image

image

image

Download

https://www.roblox.com/library/6899608114/Volt-Plugin

Framework? What’s this used for? Like an FPS Framework or- Something highly unrelated?

It’s a bad idea in the extremely rare case of someone with the name LocalPlayer joining the game. I’ve seen games being broken because players, who had their names coincidentally be the properties or events of the Players service, broke the whole server handler.
It’s bad practice not to use IsClient.

I never stated to really explicitly just use LocalPlayer, RunService:IsClient is of course the main way and good practice anyways.

what even is a game framework?

Game frameworks act as ways to simplify game development and provide tools to make game development easier. Volt is a general-purpose framework. Let’s say you were making a money system for your game. You want the server to handle and store player money. You want the client to be able to get how much money a player has for let’s say a Shop GUI. Normally you would have to write a lot of code to get this done. You would have to write a module for storing the player money data, a server script for handling the remote function for getting player money, then also write a way for the server script to interact with the module storing the data. Don’t forget about actually having to create and organize all these scripts and the remote function.

With Volt you can do all this in two scripts. And organizing? Volt provides a nice path system that will simplify game:GetService('ReplicatedStorage'):FindFirstChild('Something'):FindFirstChild('SomethingElse') down to 'Something/SomethingElse'. Using the Volt framework you have one script for your money that handles storing it as well as registering bridges, a Volt feature for communicating between the client and server, and another script for your client that will just handle your GUI.

There’s a nice in-depth example over here you can check out if you want to see something similar in code.

@Trickstaarz Since you asked the same question feel free to read this

2 Likes