seperated client and server state, input mapper
This commit is contained in:
parent
44f63f8deb
commit
d5b77a9044
10 changed files with 104 additions and 16 deletions
|
@ -6,7 +6,7 @@ import { Host } from "ReplicatedStorage/hosts"
|
|||
import { tags } from "./boundTags"
|
||||
import { Model } from "./components"
|
||||
import { start as startReplication, stop as stopReplication } from "./replication"
|
||||
import { State } from "./state"
|
||||
import { clientState, serverState } from "./state"
|
||||
import { start as startSystems, stop as stopSystems } from "./systems"
|
||||
import { start as startTags, stop as stopTags } from "./tags"
|
||||
|
||||
|
@ -22,10 +22,9 @@ let connections:
|
|||
}
|
||||
| undefined
|
||||
|
||||
export function start(host: Host): [World, State] {
|
||||
export function start<S extends object>(host: Host, state: S): [World, S] {
|
||||
if (connections) throw "ECS already running."
|
||||
|
||||
const state: State = new State()
|
||||
const world = new World()
|
||||
const debug = new Debugger(Plasma)
|
||||
debug.authorize = authorize
|
||||
|
@ -46,11 +45,15 @@ export function start(host: Host): [World, State] {
|
|||
})
|
||||
|
||||
if (host === Host.All || host === Host.Server) {
|
||||
const _ServerState = state as serverState
|
||||
|
||||
startTags(world, tags)
|
||||
}
|
||||
|
||||
if (host === Host.All || host === Host.Client) {
|
||||
startReplication(world, state)
|
||||
const ClientState = state as clientState
|
||||
|
||||
startReplication(world, ClientState)
|
||||
|
||||
const serverDebugger = ReplicatedStorage.FindFirstChild("MatterDebugger")
|
||||
if (serverDebugger && serverDebugger.IsA("ScreenGui")) {
|
||||
|
@ -65,7 +68,7 @@ export function start(host: Host): [World, State] {
|
|||
UserInputService.InputBegan.Connect((input) => {
|
||||
if (input.KeyCode === Enum.KeyCode.F4 && authorize(Players.LocalPlayer)) {
|
||||
debug.toggle()
|
||||
state.debugEnabled = debug.enabled
|
||||
ClientState.debugEnabled = debug.enabled
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { AnyEntity, World } from "@rbxts/matter"
|
||||
import { waitForEvent } from "ReplicatedStorage/remotes"
|
||||
import * as Components from "./components"
|
||||
import { State } from "./state"
|
||||
import { clientState } from "./state"
|
||||
|
||||
type ComponentNames = keyof typeof Components
|
||||
type ComponentConstructors = (typeof Components)[ComponentNames]
|
||||
|
@ -16,13 +16,13 @@ let connection: RBXScriptConnection | undefined
|
|||
* Starts the replication receiver.
|
||||
*
|
||||
* @param world - The world to replicate components in
|
||||
* @param state - The global state for the ECS
|
||||
* @param ClientState - The client state for the ECS
|
||||
*/
|
||||
export function start(world: World, state: State): void {
|
||||
export function start(world: World, ClientState: clientState): void {
|
||||
if (connection) return
|
||||
|
||||
function debugPrint(message: string, args: () => (string | number)[]): void {
|
||||
if (state.debugEnabled) {
|
||||
if (ClientState.debugEnabled) {
|
||||
print("ECS Replication>", string.format(message, ...args()))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,21 @@
|
|||
/* eslint-disable roblox-ts/no-private-identifier */
|
||||
|
||||
import { InputKind } from "ReplicatedStorage/inputKind"
|
||||
|
||||
/**
|
||||
* The global ECS state.
|
||||
* The client ECS state.
|
||||
*/
|
||||
export class State {
|
||||
export class clientState {
|
||||
[index: string]: unknown,
|
||||
// eslint-disable-next-line roblox-ts/no-private-identifier
|
||||
debugEnabled = false
|
||||
isJumping = false
|
||||
isRunning = false
|
||||
lastProcessedCommand?: InputKind
|
||||
}
|
||||
|
||||
/**
|
||||
* The server ECS state.
|
||||
*/
|
||||
export class serverState {
|
||||
[index: string]: unknown
|
||||
}
|
44
src/ReplicatedStorage/ecs/systems/client/inputMapper.ts
Normal file
44
src/ReplicatedStorage/ecs/systems/client/inputMapper.ts
Normal file
|
@ -0,0 +1,44 @@
|
|||
import { useDeltaTime, useEvent, useThrottle, World } from "@rbxts/matter"
|
||||
import { UserInputService } from "@rbxts/services"
|
||||
import { clientState } from "ReplicatedStorage/ecs/state"
|
||||
import { InputKind } from "ReplicatedStorage/inputKind"
|
||||
|
||||
let holdDuration = 0
|
||||
function inputMapper(_: World, client: clientState): void {
|
||||
for (const [, input, gpe] of useEvent(UserInputService, "InputBegan")) {
|
||||
if (gpe) return undefined
|
||||
if (input.KeyCode !== Enum.KeyCode.Unknown) {
|
||||
client.lastProcessedCommand = InputKind.KeyDown(input.KeyCode)
|
||||
} else if (input.UserInputType === Enum.UserInputType.MouseButton1) {
|
||||
if (useThrottle(0.5)) {
|
||||
client.lastProcessedCommand = InputKind.PointerClick
|
||||
return undefined
|
||||
}
|
||||
client.lastProcessedCommand = InputKind.DoubleClick
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
|
||||
for (const [, input, gpe] of useEvent(UserInputService, "InputEnded")) {
|
||||
if (gpe) return undefined
|
||||
|
||||
if (input.KeyCode !== Enum.KeyCode.Unknown) {
|
||||
client.lastProcessedCommand = InputKind.KeyUp(input.KeyCode)
|
||||
} else if (input.UserInputType === Enum.UserInputType.MouseButton1) {
|
||||
client.lastProcessedCommand = InputKind.HoldRelease
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
|
||||
if (UserInputService.IsMouseButtonPressed(Enum.UserInputType.MouseButton1)) {
|
||||
holdDuration += useDeltaTime()
|
||||
client.lastProcessedCommand = InputKind.Hold(holdDuration)
|
||||
return
|
||||
}
|
||||
|
||||
holdDuration = 0
|
||||
client.lastProcessedCommand = undefined
|
||||
return
|
||||
}
|
||||
|
||||
export = inputMapper
|
16
src/ReplicatedStorage/inputKind.ts
Normal file
16
src/ReplicatedStorage/inputKind.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
import variantModule, { TypeNames, VariantOf } from "@rbxts/variant"
|
||||
|
||||
export const InputKind = variantModule({
|
||||
// Sub-messages
|
||||
KeyDown: (key: Enum.KeyCode) => ({ key }),
|
||||
KeyUp: (key: Enum.KeyCode) => ({ key }),
|
||||
Hold: (duration: number) => ({ duration }),
|
||||
|
||||
// Messages
|
||||
HoldRelease: {},
|
||||
DoubleClick: {},
|
||||
PointerMove: {},
|
||||
PointerClick: {}
|
||||
})
|
||||
|
||||
export type InputKind<T extends TypeNames<typeof InputKind> = undefined> = VariantOf<typeof InputKind, T>
|
Loading…
Add table
Add a link
Reference in a new issue