Chat about this codebase

AI-powered code exploration

Online

Project Overview

Rayfield is a modular TypeScript framework that demonstrates domain-driven backend architecture. It provides an opinionated structure for defining data models, encapsulating business logic, and exposing a GraphQL API.

Main Capabilities

  • Auto-generate CRUD GraphQL schema from declarative data models
  • Encapsulate use-case logic in isolated service classes
  • Apply hooks and policies for validation, authorization, and side-effects
  • Integrate common concerns (authentication, file storage, mailing) via plugins
  • Offer a CLI for project scaffolding and code generation

Maintenance Status

Rayfield’s core is non-functional in its current state. The underlying data-model definitions have evolved, and the schema generation step fails until models are updated. No active releases address this incompatibility.

Why Study or Fork Rayfield

  • Explore a clear separation between domain entities, use-cases, and API layer
  • Reuse or modernize its plugin hooks for auth, files, and email workflows
  • Adapt its CLI-driven code-generation approach for new projects
  • Contribute a data-model migration to revive the framework

Getting Started

Clone the repository and inspect the architecture:

git clone https://github.com/AllahSolutions/rayfield.git
cd rayfield
npm install
  1. Open src/models/ and align definitions with current schema conventions.

  2. Run the code generator (once models update):

    npm run generate
    npm run dev
    
  3. Explore src/use-cases/, src/plugins/, and the generated src/graphql/ schema.

  4. Submit pull requests to update data models and restore functionality.

Getting Started

Follow these steps to import Rayfield into your Roblox game, create your first window, and add a simple button in under five minutes.

1. Install Rayfield

  1. Open Roblox Studio and your target place.
  2. In the Explorer, right-click ReplicatedStorageInsert ObjectModuleScript.
  3. Rename the new ModuleScript to Rayfield.
  4. Paste the contents of main.lua into ReplicatedStorage.Rayfield and save.

2. Initialize a Window

Create a LocalScript under StarterPlayerScripts (or StarterGui) and add:

-- StarterPlayerScripts/InitRayfield.lua
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Rayfield = require(ReplicatedStorage.Rayfield)

-- Create a basic window
local Window = Rayfield:CreateWindow({
    Name = "Demo UI",                      -- Window title in top bar
    LoadingTitle = "Welcome to Demo UI",   -- Splash screen title
    LoadingSubtitle = "Loading...",        -- Splash screen subtitle
    ConfigurationSaving = {
        Enabled = true,                    -- Enable config file saving
        FolderName = nil,                  -- Defaults to "RayfieldConfigs"
        FileName = "UserSettings"          -- Name of the config file
    },
    Discord = {
        Enabled = false,                   -- Discord invite button
        Invite = ""                        -- Your server invite code
    },
    KeySystem = false                       -- Disable built-in keybind check
})

Save and run the game; you should see a loading splash, then an empty window titled Demo UI.

3. Add a Button

Extend the same script to add an interactive button:

-- Add a button that notifies when clicked
Window:CreateButton({
    Name = "Click Me",                     -- Button label
    Callback = function()
        Rayfield:Notify({                 -- Built-in notification pop-up
            Title = "Success",
            Content = "You clicked the button!"
        })
    end
})

Full example:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Rayfield = require(ReplicatedStorage.Rayfield)

local Window = Rayfield:CreateWindow({
    Name = "Demo UI",
    LoadingTitle = "Welcome to Demo UI",
    LoadingSubtitle = "Loading...",
    ConfigurationSaving = { Enabled = true },
    Discord = { Enabled = false },
    KeySystem = false
})

Window:CreateButton({
    Name = "Click Me",
    Callback = function()
        Rayfield:Notify({
            Title = "Success",
            Content = "You clicked the button!"
        })
    end
})

Run the game. You now have a functional Rayfield window with a working button—your first success!

API Reference

Rayfield exposes a single module RayfieldLibrary that you require to bootstrap your UI. Use its methods to create windows, tabs, and UI elements, and to trigger notifications or theme changes.


Library Bootstrap

require & CreateWindow

Signature

local RayfieldLibrary = require(path_to_main)

-- Create the main UI window
local Window = RayfieldLibrary:CreateWindow(settings: table): Window

Parameters (settings table)
• Name (string): window title shown in header.
• LoadingTitle (string, optional): text shown during UI load animation.
• ConfigurationSaving (table, optional): auto save/load settings
 – Enabled (bool)
 – FileName (string)
 – FolderName (string)

Returns
• Window object

Example

local Rayfield = require(game.ReplicatedStorage.Rayfield)
local Window = Rayfield:CreateWindow({
  Name = "My Admin Panel",
  LoadingTitle = "Initializing…",
  ConfigurationSaving = {
    Enabled    = true,
    FileName   = "AdminConfig",
    FolderName = "AdminConfigs"
  }
})

Window Object

Once created, a Window lets you add tabs and control high-level features.

Methods

CreateTab
local Tab = Window:CreateTab(title: string): Tab

title: text label for the tab.
Returns a Tab object.

SetTitle
Window:SetTitle(newTitle: string)

• Updates window header text.

(Global) ChangeTheme
RayfieldLibrary:ChangeTheme(theme: table)

theme: table of color overrides (see Themes in repository).


Tab Object

A Tab groups related UI elements. All Create… methods return the element descriptor for further control.

CreateButton

Tab:CreateButton(options: table): Button

Options
• Name (string): label text.
• Description (string, optional): tooltip or subtitle.
• Callback (function): invoked on click.

Example

Tab:CreateButton({
  Name = "Teleport to Spawn",
  Description = "Instantly move to spawn",
  Callback = function()
    game.Players.LocalPlayer.Character.HumanoidRootPart.CFrame =
      workspace.SpawnLocation.CFrame
  end
})

CreateToggle

Tab:CreateToggle(options: table): Toggle

Options
• Name (string)
• Flag (string, optional): for config persistence
• CurrentValue (bool)
• Callback (function(state: bool))

Example

Tab:CreateToggle({
  Name = "Enable Godmode",
  Flag = "godmode",
  CurrentValue = false,
  Callback = function(isOn)
    _G.Godmode = isOn
  end
})

CreateSlider

Tab:CreateSlider(options: table): Slider

Options
• Name (string)
• Range (table[number, number]) e.g. {0,100}
• Increment (number)
• Suffix (string, optional)
• CurrentValue (number)
• Flag (string, optional)
• Callback (function(value: number))

Example

Tab:CreateSlider({
  Name = "Walkspeed",
  Range = {16, 100},
  Increment = 1,
  Suffix = "studs/s",
  CurrentValue = 16,
  Flag = "walkspeed",
  Callback = function(v)
    game.Players.LocalPlayer.Character.Humanoid.WalkSpeed = v
  end
})

CreateDropdown

Tab:CreateDropdown(options: table): Dropdown

Options
• Name (string)
• Options (array[string])
• CurrentOption (string)
• MultiSelect (bool, optional)
• Flag (string, optional)
• Callback (function(selected: string or table))

Example

Tab:CreateDropdown({
  Name = "Select Tool",
  Options = {"Sword","Shield","Bow"},
  CurrentOption = "Sword",
  Flag = "fav_tool",
  Callback = function(choice)
    print("Equipped:", choice)
  end
})

CreateColorpicker

Tab:CreateColorpicker(options: table): Colorpicker

Options
• Name (string)
• Flag (string, optional)
• CurrentColor (Color3)
• Callback (function(color: Color3))

Example

Tab:CreateColorpicker({
  Name = "ESP Color",
  Flag = "esp_color",
  CurrentColor = Color3.fromRGB(255,0,0),
  Callback = function(c)
    ESP.HighlightColor = c
  end
})

CreateKeybind

Tab:CreateKeybind(options: table): Keybind

Options
• Name (string)
• Flag (string, optional)
• Mode (string): "Toggle" or "Hold"
• Default (Enum.KeyCode)
• Callback (function(key: Enum.KeyCode))

Example

Tab:CreateKeybind({
  Name = "Toggle UI",
  Flag = "toggle_ui",
  Mode = "Toggle",
  Default = Enum.KeyCode.F,
  Callback = function(key)
    Window:Toggle()  -- show/hide window
  end
})

Notifications

RayfieldLibrary:Notify

RayfieldLibrary:Notify(options: table)

Options
• Title (string)
• Content (string)
• Duration (number, optional, seconds)

Example

RayfieldLibrary:Notify({
  Title = "Warning",
  Content = "Low health detected",
  Duration = 5
})

Configuration (Save/Load)

Refer to Configuration Saving and Loading for SaveConfiguration() and LoadConfiguration() details. After building all tabs and elements, call:

RayfieldLibrary:LoadConfiguration()

to restore persisted flags. Call RayfieldLibrary:SaveConfiguration() to write manual updates.

Configuration & Themes

Rayfield centralizes theme management and configuration persistence. Use ConfigurationSaving in CreateWindow to enable save/load, and define or update themes via Theme, UpdateTheme, and SetTheme.

1. Configuration Persistence

1.1 Enable Saving & Loading

Pass a ConfigurationSaving table when creating your window:

local Rayfield = loadstring(game:HttpGet("https://raw.githubusercontent.com/AllahSolutions/rayfield/main/source.lua"))()

local Window = Rayfield:CreateWindow({
    Name = "My Game UI",
    LoadingTitle = "Initializing...",
    ConfigurationSaving = {
        Enabled   = true,           -- master switch
        FolderName= "GameConfigs",  -- subfolder in your executor’s workspace
        FileName  = "DefaultConfig",-- default config file
        AutoSave  = false,          -- save on every change
        AutoLoad  = true            -- load on window init
    },
    Theme = {
        TextColor       = Color3.fromRGB(255,255,255),
        MainColor       = Color3.fromRGB(30,30,30),
        AccentColor     = Color3.fromRGB(0,170,255),
        BackgroundColor = Color3.fromRGB(20,20,20)
    }
})

1.2 Runtime Save & Load

Use these methods to persist or restore UI element states:

-- Save current state as "Session1"
Window:SaveConfiguration("Session1")

-- Load values from "Session1"
Window:LoadConfiguration("Session1")

Combine with buttons or keybinds for manual control:

Window:CreateButton({
    Name = "Save Config",
    Callback = function() Window:SaveConfiguration("QuickSave") end
})

Window:CreateButton({
    Name = "Load Config",
    Callback = function() Window:LoadConfiguration("QuickSave") end
})

2. Theme Customization

2.1 Initial Theme Definition

Define your base look when calling CreateWindow (see above). Fields:

  • TextColor: default text
  • MainColor: panels, popups
  • AccentColor: buttons, sliders
  • BackgroundColor: window backdrop

2.2 Update Theme at Runtime

Change part or all of the theme without rebuilding the UI:

-- Update only accent and background colors
Window:UpdateTheme({
    AccentColor     = Color3.fromRGB(255,100,100),
    BackgroundColor = Color3.fromRGB(15,15,15)
})

This refreshes every element using those theme fields.

2.3 Replace Entire Theme

Apply a completely new theme object:

local DarkTheme = {
    TextColor       = Color3.fromRGB(200,200,200),
    MainColor       = Color3.fromRGB(40,40,40),
    AccentColor     = Color3.fromRGB(100,200,100),
    BackgroundColor = Color3.fromRGB(10,10,10)
}

Window:SetTheme(DarkTheme)

2.4 Light/Dark Toggle Example

Combine toggle element with theme switching:

-- Define themes
local LightTheme = {
    TextColor       = Color3.new(0,0,0),
    MainColor       = Color3.fromRGB(230,230,230),
    AccentColor     = Color3.fromRGB(0,120,215),
    BackgroundColor = Color3.fromRGB(245,245,245)
}

local DarkTheme = {
    TextColor       = Color3.fromRGB(255,255,255),
    MainColor       = Color3.fromRGB(30,30,30),
    AccentColor     = Color3.fromRGB(0,170,255),
    BackgroundColor = Color3.fromRGB(20,20,20)
}

-- Add toggle to switch
Window:CreateToggle({
    Name     = "Dark Mode",
    Current  = true,
    Callback = function(isDark)
        if isDark then
            Window:SetTheme(DarkTheme)
        else
            Window:SetTheme(LightTheme)
        end
    end
})

This instantly swaps colors across all UI elements.