Compare commits

..

No commits in common. "add6db3bb6dcc65fdef32060191317e7f08c0c33" and "b1c03da589436c15f2b2dee3efa4895c4a4d7e1c" have entirely different histories.

21 changed files with 314 additions and 109 deletions

1
.env.example Normal file
View file

@ -0,0 +1 @@
ROBLOXSECURITY="_|WARNING:-DO-NOT-SHARE-THIS.--Sharing-this-will-allow-someone-to-log-in-as-you-and-to-steal-your-ROBUX-and-items.|youReallyThoughtBuddy"

6
.github/dependabot.yml vendored Normal file
View file

@ -0,0 +1,6 @@
version: 2
updates:
- package-ecosystem: "npm" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "daily"

36
.github/workflows/build.yml vendored Normal file
View file

@ -0,0 +1,36 @@
name: Build
on:
pull_request:
push:
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v3
- name: Set Node.js 16.x
uses: actions/setup-node@v3
with:
node-version: 16.x
- name: Run install
uses: borales/actions-yarn@v4
with:
cmd: install # will run `yarn install` command
- name: Install aftman
uses: ok-nick/setup-aftman@v0.3.0
- name: Build
uses: borales/actions-yarn@v4
with:
cmd: build # will run `yarn build` command
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:
name: goopler
path: build.rbxl

37
.github/workflows/deploy.yml vendored Normal file
View file

@ -0,0 +1,37 @@
name: Deploy
on:
pull_request:
push:
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v3
- name: Set Node.js 16.x
uses: actions/setup-node@v3
with:
node-version: 16.x
- name: Run install
uses: borales/actions-yarn@v4
with:
cmd: install # will run `yarn install` command
- name: Install aftman
uses: ok-nick/setup-aftman@v0.3.0
- name: Build
uses: borales/actions-yarn@v4
with:
cmd: build # will run `yarn build` command
- name: Deploy project
run: mantle deploy -e default
env:
ROBLOSECURITY: ${{ secrets.ROBLOSECURITY }}
MANTLE_AWS_ACCESS_KEY_ID: ${{ secrets.MANTLE_AWS_ACCESS_KEY_ID }}
MANTLE_AWS_SECRET_ACCESS_KEY: ${{ secrets.MANTLE_AWS_SECRET_ACCESS_KEY }}

27
.github/workflows/lint.yml vendored Normal file
View file

@ -0,0 +1,27 @@
name: Lint
on:
pull_request:
push:
jobs:
build:
name: ESLint
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v3
- name: Set Node.js 16.x
uses: actions/setup-node@v3
with:
node-version: 16.x
- name: Run install
uses: borales/actions-yarn@v4
with:
cmd: install # will run `yarn install` command
- name: Lint
uses: borales/actions-yarn@v4
with:
cmd: lint # will run `yarn lint` command

16
.gitignore vendored
View file

@ -1,15 +1,21 @@
# Builds # builds
/out /out
build.rbxl build.rbxl
*.tsbuildinfo *.tsbuildinfo
# Deps # deps
/node_modules /node_modules
/include /include
# Mac junk # mac users.. stop making these files or im gonna get mad 😡😡😡
.DS_Store .DS_Store
/__MACOSX /__MACOSX
# Logs # logs
*.log *.log
# my secrets 😍😎
.env
# we use remote stuff now
.mantle-state.yml

View file

@ -4,4 +4,5 @@
# To add a new tool, add an entry to this table. # To add a new tool, add an entry to this table.
[tools] [tools]
rojo = "rojo-rbx/rojo@7.3.0" rojo = "rojo-rbx/rojo@7.3.0"
run-in-roblox = "rojo-rbx/run-in-roblox@0.3.0" run-in-roblox = "rojo-rbx/run-in-roblox@0.3.0"
mantle = "blake-mealey/mantle@0.11.9"

29
mantle.yml Normal file
View file

@ -0,0 +1,29 @@
environments:
- label: default
target:
experience:
icon: marketing/gameIcon.jpg
thumbnails:
- marketing/gameThumbnailDefault.jpg
configuration:
genre: fps
playableDevices: [computer]
privateServers:
price: 50
enableStudioAccessToApis: true
avatarType: r6
places:
start:
file: build.rbxl
configuration:
name: Goopler
description: |-
Read my github repo reidlabwastaken/goopler if u can hahaha
maxPlayerCount: 100
state:
remote:
region: us-west-2
bucket: goopler-mantle-states
key: goopler

BIN
marketing/gameIcon.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

View file

@ -20,7 +20,8 @@
"watch": "rbxtsc -w --rojo default.project.json --verbose", "watch": "rbxtsc -w --rojo default.project.json --verbose",
"lint": "eslint src tests --max-warnings 0", "lint": "eslint src tests --max-warnings 0",
"serve": "rojo serve default.project.json", "serve": "rojo serve default.project.json",
"test": "yarn run build && run-in-roblox --place build.rbxl --script out/tests/runners/run.server.lua" "test": "yarn run build && run-in-roblox --place build.rbxl --script out/tests/runners/run.server.lua",
"deploy": "yarn run build && mantle deploy -e default"
}, },
"devDependencies": { "devDependencies": {
"@rbxts/compiler-types": "^2.1.1-types.0", "@rbxts/compiler-types": "^2.1.1-types.0",
@ -33,7 +34,6 @@
}, },
"dependencies": { "dependencies": {
"@rbxts/character-promise": "^1.0.2", "@rbxts/character-promise": "^1.0.2",
"@rbxts/log": "^0.6.3",
"@rbxts/matter": "^0.6.2-ts.6", "@rbxts/matter": "^0.6.2-ts.6",
"@rbxts/plasma": "^0.4.1-ts.1", "@rbxts/plasma": "^0.4.1-ts.1",
"@rbxts/rewire": "^0.3.0", "@rbxts/rewire": "^0.3.0",

View file

@ -7,25 +7,32 @@ An in-dev game that I plan to make a shooter game out of.
— reidlab — reidlab
# Setup
When you first setup this repository, you probably want to add your `.ROBLOSECURITY` cookie into the `.env` file for automatic deployment with [Mantle](https://mantledeploy.vercel.app/). You also should change the ID of the game.
# Hacks # Hacks
* I get a strange error about private identifiers in [`./src/ReplicatedStorage/ecs/state.ts`](./src/ReplicatedStorage/ecs/state.ts) * I get a strange error about private identifiers in [`./src/ReplicatedStorage/ecs/state.ts`](./src/ReplicatedStorage/ecs/state.ts)
* I decided to omit the "TS" folder from [`./default.project.json:40`](./default.project.json) due to the script override not working in Health.server.ts in StarterCharacterScripts. * I decided to omit the "TS" folder from [`./default.project.json:40`](./default.project.json) due to the script override not working in Health.server.ts in StarterCharacterScripts.
# Todo # Todo
### High priority ### High priority
* Fix automatic deployment. Its fixed itself, but its broken again. By the time this commit goes through I bet it will work again. Honestly super weird. Just make it consistant
* Add tests * Add tests
* Add guns. Try it in default roblox-ts and slowly reimplement it into our component system. * Add guns. Try it in default roblox-ts and slowly reimplement it into our component system
#### Medium priority #### Medium priority
* Crouching * Crouching
* Animations * Animations
* Change remote state to a provider where I dont have to worry about money
* Seperate dev&prod environments (maybe later??? the game is very early stage so idk)
* Migrate todo to somewhere else like the issues tab
##### Low priority ##### Low priority
* Camera bobble * Camera bobble
* Add the bound tags in [`./src/ReplicatedStorage/ecs/boundTags.ts`](./src/ReplicatedStorage/ecs/boundTags.ts) * Add the bound tags in [`./src/ReplicatedStorage/ecs/boundTags.ts`](./src/ReplicatedStorage/ecs/boundTags.ts)
* Cooler sprinting! (Tween fov and speed) * Cooler sprinting!! (Tween fov and speed)
* Crouching? * Crouching?
# Fixes # Fixes
### High Priority ### High Priority
* Currently, when resetting, sometimes your health goes back up. This is due to the reconciliation of health. Simply put, your health is not being set to zero inside of our entity component system, due to us not having the reset event currently like that. See it here: [StarterGui.SetCore](https://create.roblox.com/docs/reference/engine/classes/StarterGui#SetCore) It uses BindableEvents. * Currently, when resetting, sometimes your health goes back up. This is due to the reconciliation of health. Simply put, your health is not being set to zero inside of our entity component system, due to us not having the reset event currently like that. See it here: [StarterGui.SetCore](https://create.roblox.com/docs/reference/engine/classes/StarterGui#SetCore) It uses BindableEvents and stuff idk
#### Medium priority #### Medium priority
##### Low priority ##### Low priority

View file

@ -45,9 +45,9 @@ export function start<S extends object>(host: Host, state: S): [World, S] {
}) })
if (host === Host.All || host === Host.Server) { if (host === Host.All || host === Host.Server) {
const ServerState = state as serverState const _ServerState = state as serverState
startTags(world, tags, ServerState) startTags(world, tags)
} }
if (host === Host.All || host === Host.Client) { if (host === Host.All || host === Host.Client) {

View file

@ -6,17 +6,27 @@ import { clientState } from "./state"
type ComponentNames = keyof typeof Components type ComponentNames = keyof typeof Components
type ComponentConstructors = (typeof Components)[ComponentNames] type ComponentConstructors = (typeof Components)[ComponentNames]
const DEBUG_SPAWN = "Spawn %ds%d with %s"
const DEBUG_DESPAWN = "Despawn %ds%d"
const DEBUG_MODIFY = "Modify %ds%d adding %s, removing %s"
let connection: RBXScriptConnection | undefined let connection: RBXScriptConnection | undefined
/** /**
* Starts the replication receiver. * Starts the replication receiver.
* *
* @param world - The world to replicate components in * @param world - The world to replicate components in
* @param client - The client state for the ECS * @param ClientState - The client state for the ECS
*/ */
export function start(world: World, client: clientState): void { export function start(world: World, ClientState: clientState): void {
if (connection) return if (connection) return
function debugPrint(message: string, args: () => (string | number)[]): void {
if (ClientState.debugEnabled) {
print("ECS Replication>", string.format(message, ...args()))
}
}
const replicationEvent = waitForEvent("EcsReplication") const replicationEvent = waitForEvent("EcsReplication")
const serverToClientEntity = new Map<string, AnyEntity>() const serverToClientEntity = new Map<string, AnyEntity>()
@ -28,11 +38,7 @@ export function start(world: World, client: clientState): void {
if (clientId !== undefined && next(componentMap)[0] === undefined) { if (clientId !== undefined && next(componentMap)[0] === undefined) {
world.despawn(clientId) world.despawn(clientId)
serverToClientEntity.delete(serverId) serverToClientEntity.delete(serverId)
client.logger.Debug( debugPrint(DEBUG_DESPAWN, () => [clientId, serverId])
"ECS Replication> Despawn {@clientId}s{@serverId}",
clientId,
serverId
)
continue continue
} }
@ -66,12 +72,7 @@ export function start(world: World, client: clientState): void {
if (clientId === undefined) { if (clientId === undefined) {
const clientId = world.spawn(...componentsToInsert) const clientId = world.spawn(...componentsToInsert)
serverToClientEntity.set(serverId, clientId) serverToClientEntity.set(serverId, clientId)
client.logger.Debug( debugPrint(DEBUG_SPAWN, () => [clientId, serverId, insertNames.join(",")])
"ECS Replication> Spawn {@clientId}s{@serverId} with {@insertNames}",
clientId,
serverId,
insertNames.join(",")
)
} else { } else {
if (componentsToInsert.size() > 0) { if (componentsToInsert.size() > 0) {
world.insert(clientId, ...componentsToInsert) world.insert(clientId, ...componentsToInsert)
@ -81,13 +82,12 @@ export function start(world: World, client: clientState): void {
world.remove(clientId, ...componentsToRemove) world.remove(clientId, ...componentsToRemove)
} }
client.logger.Debug( debugPrint(DEBUG_MODIFY, () => [
"ECS Replication> Modify {@clientId}s{serverId} adding {@insertNames}, removing {@removeNames}",
clientId, clientId,
serverId, serverId,
insertNames.size() > 0 ? insertNames.join(", ") : "nothing", insertNames.size() > 0 ? insertNames.join(", ") : "nothing",
removeNames.size() > 0 ? removeNames.join(", ") : "nothing" removeNames.size() > 0 ? removeNames.join(", ") : "nothing"
) ])
} }
} }
} }

View file

@ -1,54 +1,23 @@
/* eslint-disable roblox-ts/no-private-identifier */ /* eslint-disable roblox-ts/no-private-identifier */
import { CharacterRigR6 } from "@rbxts/character-promise" import { CharacterRigR6 } from "@rbxts/character-promise"
import { Logger } from "@rbxts/log"
import { InputKind } from "ReplicatedStorage/inputKind" import { InputKind } from "ReplicatedStorage/inputKind"
/** /**
* The client ECS state. * The client ECS state.
*/ */
export class clientState { export class clientState {
constructor( [index: string]: unknown
player: Player, character?: CharacterRigR6
character: CharacterRigR6, player?: Player
debugEnabled: boolean, debugEnabled = false
isRunning: boolean, isRunning = false
// lastProcessedCommand: Inputkind,
logger: Logger
) {
this.character = character
this.player = player
this.debugEnabled = debugEnabled
this.isRunning = isRunning
// this.lastProcessedCommand = lastProcessedCommand
this.logger = logger
}
player: Player
character: CharacterRigR6
debugEnabled: boolean
isRunning: boolean
lastProcessedCommand?: InputKind lastProcessedCommand?: InputKind
logger: Logger
} }
/** /**
* The server ECS state. * The server ECS state.
*/ */
export class serverState { export class serverState {
constructor( [index: string]: unknown
logger: Logger }
) {
this.logger = logger
}
logger: Logger
}
/**
* The shared ECS state.
*/
export type sharedState = serverState & clientState

View file

@ -2,7 +2,6 @@ import { AnyEntity, Component, World } from "@rbxts/matter"
import { CollectionService } from "@rbxts/services" import { CollectionService } from "@rbxts/services"
import { getIdAttribute } from "ReplicatedStorage/idAttribute" import { getIdAttribute } from "ReplicatedStorage/idAttribute"
import { Model, Transform } from "./components" import { Model, Transform } from "./components"
import { serverState } from "./state"
export type ComponentConstructor<T extends object> = () => Component<T> export type ComponentConstructor<T extends object> = () => Component<T>
@ -16,8 +15,7 @@ const connections: RBXScriptConnection[] = []
*/ */
export function start( export function start(
world: World, world: World,
bound: ReadonlyMap<string, ComponentConstructor<object>>, bound: ReadonlyMap<string, ComponentConstructor<object>>
server: serverState
): void { ): void {
function spawnBound<T extends object>( function spawnBound<T extends object>(
instance: Instance, instance: Instance,
@ -28,13 +26,13 @@ export function start(
if (instance.PrimaryPart) { if (instance.PrimaryPart) {
primaryPart = instance.PrimaryPart primaryPart = instance.PrimaryPart
} else { } else {
server.logger.Warn("Attempted to tag a model that has no primary part: {@instance}", instance) warn("Attempted to tag a model that has no primary part:", instance)
return return
} }
} else if (instance.IsA("BasePart")) { } else if (instance.IsA("BasePart")) {
primaryPart = instance primaryPart = instance
} else { } else {
server.logger.Warn("Attempted to tag an instance that is not a Model or BasePart: {@instance}", instance) warn("Attempted to tag an instance that is not a Model or BasePart:", instance)
return return
} }

View file

@ -1,7 +1,6 @@
import { useEvent, World } from "@rbxts/matter" import { useEvent, World } from "@rbxts/matter"
import { Players } from "@rbxts/services" import { Players } from "@rbxts/services"
import * as Components from "ReplicatedStorage/ecs/components" import * as Components from "ReplicatedStorage/ecs/components"
import { serverState } from "ReplicatedStorage/ecs/state"
import { getEvent } from "ReplicatedStorage/remotes" import { getEvent } from "ReplicatedStorage/remotes"
type ComponentName = keyof typeof Components type ComponentName = keyof typeof Components
@ -21,7 +20,7 @@ const replicatedComponents: ReadonlySet<ComponentConstructor> = REPLICATED_COMPO
getEvent("EcsReplication") getEvent("EcsReplication")
function replication(world: World, server: serverState): void { function replication(world: World): void {
const replicationEvent = getEvent("EcsReplication") const replicationEvent = getEvent("EcsReplication")
let payload: Map<string, Map<ComponentName, { data?: Components.GooplerComponent }>> | undefined let payload: Map<string, Map<ComponentName, { data?: Components.GooplerComponent }>> | undefined
@ -44,7 +43,7 @@ function replication(world: World, server: serverState): void {
} }
} }
server.logger.Debug("Sending initial payload to {@player}", player) print("Sending initial payload to", player)
replicationEvent.FireClient(player, payload) replicationEvent.FireClient(player, payload)
} }

View file

@ -1,4 +1,3 @@
import Log, { Logger } from "@rbxts/log"
import { start } from "ReplicatedStorage/ecs" import { start } from "ReplicatedStorage/ecs"
import { serverState } from "ReplicatedStorage/ecs/state" import { serverState } from "ReplicatedStorage/ecs/state"
import { Host } from "ReplicatedStorage/hosts" import { Host } from "ReplicatedStorage/hosts"
@ -7,14 +6,7 @@ import { getEvent } from "ReplicatedStorage/remotes"
const HOST = Host.Server const HOST = Host.Server
const serverLogger = Logger.configure() const ServerState = new serverState()
.EnrichWithProperty("Roblox-TS Version", _VERSION)
.WriteTo(Log.RobloxOutput())
.Create()
const ServerState = new serverState(
serverLogger
)
// We only do this here at the moment to create a dummy event for replication. // We only do this here at the moment to create a dummy event for replication.
// In the future this will be created by the replication system. // In the future this will be created by the replication system.

View file

@ -1,5 +1,4 @@
import { CharacterRigR6 } from "@rbxts/character-promise" import { CharacterRigR6 } from "@rbxts/character-promise"
import Log, { Logger } from "@rbxts/log"
import { Players } from "@rbxts/services" import { Players } from "@rbxts/services"
import { start } from "ReplicatedStorage/ecs" import { start } from "ReplicatedStorage/ecs"
import { clientState } from "ReplicatedStorage/ecs/state" import { clientState } from "ReplicatedStorage/ecs/state"
@ -8,19 +7,11 @@ import { setEnvironment } from "ReplicatedStorage/idAttribute"
const HOST = Host.Client const HOST = Host.Client
const clientLogger = Logger.configure() const ClientState = new clientState()
.EnrichWithProperty("Roblox-TS Version", _VERSION)
.WriteTo(Log.RobloxOutput())
.Create()
const ClientState = new clientState( const player = Players.LocalPlayer
Players.LocalPlayer, ClientState.character = (player.Character || player.CharacterAdded.Wait()[0]) as CharacterRigR6
(Players.LocalPlayer.Character || Players.LocalPlayer.CharacterAdded.Wait()[0]) as CharacterRigR6, ClientState.player = player
false,
false,
clientLogger
)
setEnvironment(HOST) setEnvironment(HOST)
start(HOST, ClientState) start(HOST, ClientState)

View file

@ -0,0 +1,118 @@
<roblox xmlns:xmime="http://www.w3.org/2005/05/xmlmime" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.roblox.com/roblox.xsd" version="4">
<Meta name="ExplicitAutoJoints">true</Meta>
<External>null</External>
<External>nil</External>
<Item class="Part" referent="RBXE7866AEC03004D3B83A1415157AEFC3C">
<Properties>
<bool name="Anchored">false</bool>
<BinaryString name="AttributesSerialize"></BinaryString>
<float name="BackParamA">-0.5</float>
<float name="BackParamB">0.5</float>
<token name="BackSurface">0</token>
<token name="BackSurfaceInput">0</token>
<float name="BottomParamA">-0.5</float>
<float name="BottomParamB">0.5</float>
<token name="BottomSurface">0</token>
<token name="BottomSurfaceInput">0</token>
<CoordinateFrame name="CFrame">
<X>19</X>
<Y>2.00000119</Y>
<Z>22</Z>
<R00>1</R00>
<R01>0</R01>
<R02>0</R02>
<R10>0</R10>
<R11>1</R11>
<R12>0</R12>
<R20>0</R20>
<R21>0</R21>
<R22>1</R22>
</CoordinateFrame>
<bool name="CanCollide">true</bool>
<bool name="CanQuery">true</bool>
<bool name="CanTouch">true</bool>
<bool name="CastShadow">true</bool>
<string name="CollisionGroup">Default</string>
<int name="CollisionGroupId">0</int>
<Color3uint8 name="Color3uint8">4288914085</Color3uint8>
<PhysicalProperties name="CustomPhysicalProperties">
<CustomPhysics>false</CustomPhysics>
</PhysicalProperties>
<bool name="EnableFluidForces">false</bool>
<float name="FrontParamA">-0.5</float>
<float name="FrontParamB">0.5</float>
<token name="FrontSurface">0</token>
<token name="FrontSurfaceInput">0</token>
<float name="LeftParamA">-0.5</float>
<float name="LeftParamB">0.5</float>
<token name="LeftSurface">0</token>
<token name="LeftSurfaceInput">0</token>
<bool name="Locked">false</bool>
<bool name="Massless">false</bool>
<token name="Material">256</token>
<string name="MaterialVariantSerialized"></string>
<string name="Name">NotABasePart</string>
<CoordinateFrame name="PivotOffset">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
<R00>1</R00>
<R01>0</R01>
<R02>0</R02>
<R10>0</R10>
<R11>1</R11>
<R12>0</R12>
<R20>0</R20>
<R21>0</R21>
<R22>1</R22>
</CoordinateFrame>
<float name="Reflectance">0</float>
<float name="RightParamA">-0.5</float>
<float name="RightParamB">0.5</float>
<token name="RightSurface">0</token>
<token name="RightSurfaceInput">0</token>
<int name="RootPriority">0</int>
<Vector3 name="RotVelocity">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<int64 name="SourceAssetId">-1</int64>
<BinaryString name="Tags">RXhhbXBsZQ==</BinaryString>
<float name="TopParamA">-0.5</float>
<float name="TopParamB">0.5</float>
<token name="TopSurface">0</token>
<token name="TopSurfaceInput">0</token>
<float name="Transparency">0</float>
<Vector3 name="Velocity">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<token name="formFactorRaw">1</token>
<token name="shape">1</token>
<Vector3 name="size">
<X>4</X>
<Y>4</Y>
<Z>4</Z>
</Vector3>
</Properties>
<Item class="Decal" referent="RBXC28C593C6B7F48B6AF6E20AAFD33B531">
<Properties>
<BinaryString name="AttributesSerialize"></BinaryString>
<Color3 name="Color3">
<R>1</R>
<G>1</G>
<B>1</B>
</Color3>
<token name="Face">5</token>
<string name="Name">Remilia Scarlet deka fumo</string>
<int64 name="SourceAssetId">9961773472</int64>
<BinaryString name="Tags"></BinaryString>
<Content name="Texture"><url>http://www.roblox.com/asset/?id=9961773438</url></Content>
<float name="Transparency">0</float>
<int name="ZIndex">1</int>
</Properties>
</Item>
</Item>
</roblox>

View file

@ -91,23 +91,11 @@
resolved "https://registry.yarnpkg.com/@rbxts/compiler-types/-/compiler-types-2.1.1-types.0.tgz#a1f02b57402dffec474dd6656ec1d8a897b9756b" resolved "https://registry.yarnpkg.com/@rbxts/compiler-types/-/compiler-types-2.1.1-types.0.tgz#a1f02b57402dffec474dd6656ec1d8a897b9756b"
integrity sha512-wBRma9MgPbOxvCaQEUvraHLHAmLFGW9R6fT65+MBu3uCYM6vUNWj8l4dHRxgkUK8lnGYdGWxsr/sZFk8sdvwog== integrity sha512-wBRma9MgPbOxvCaQEUvraHLHAmLFGW9R6fT65+MBu3uCYM6vUNWj8l4dHRxgkUK8lnGYdGWxsr/sZFk8sdvwog==
"@rbxts/log@^0.6.3":
version "0.6.3"
resolved "https://registry.yarnpkg.com/@rbxts/log/-/log-0.6.3.tgz#65b51a897a2d646457db95b563ade3313e08d0be"
integrity sha512-YZpDvjL7yif9aYuNAkuM9vnegcwQmOwX0CfvGfWvrzCpmARY4Ey2pTMhoEgxKo36HcdPPi3aLxmcuvn0NHrPPg==
dependencies:
"@rbxts/message-templates" "^0.3.1"
"@rbxts/matter@^0.6.2-ts.6": "@rbxts/matter@^0.6.2-ts.6":
version "0.6.4" version "0.6.4"
resolved "https://registry.yarnpkg.com/@rbxts/matter/-/matter-0.6.4.tgz#49ff6ce56bada1ce7c5e2715a05daaa3fb7615e6" resolved "https://registry.yarnpkg.com/@rbxts/matter/-/matter-0.6.4.tgz#49ff6ce56bada1ce7c5e2715a05daaa3fb7615e6"
integrity sha512-84naXqNpUfb5aCEcKf99wdqNnNAuwXh4B73GMQBzrUGiF70m0EWTdmm0qHihdlghGPrCRBSFeYK5esMJvKs/SQ== integrity sha512-84naXqNpUfb5aCEcKf99wdqNnNAuwXh4B73GMQBzrUGiF70m0EWTdmm0qHihdlghGPrCRBSFeYK5esMJvKs/SQ==
"@rbxts/message-templates@^0.3.1":
version "0.3.2"
resolved "https://registry.yarnpkg.com/@rbxts/message-templates/-/message-templates-0.3.2.tgz#85169980cf73f659282aa9846290ceaf06967167"
integrity sha512-79onYskH3pgrBT73Zs+biQ31vAVvupKQaxGNWGjyGsxwNhO2YaN/qkut0bvOshaGa+ZzqAXApRVrN8ifIMPiMQ==
"@rbxts/plasma@^0.4.1-ts.1": "@rbxts/plasma@^0.4.1-ts.1":
version "0.4.1-ts.1" version "0.4.1-ts.1"
resolved "https://registry.yarnpkg.com/@rbxts/plasma/-/plasma-0.4.1-ts.1.tgz#3d8db367c3220e6b6953cdddbf8af9f087165392" resolved "https://registry.yarnpkg.com/@rbxts/plasma/-/plasma-0.4.1-ts.1.tgz#3d8db367c3220e6b6953cdddbf8af9f087165392"