diff --git a/assets/Scenes/testscene1/scene.ts b/assets/Scenes/testscene1/scene.ts new file mode 100644 index 00000000..0a99cc92 --- /dev/null +++ b/assets/Scenes/testscene1/scene.ts @@ -0,0 +1,13 @@ +import { Scene } from "/Scripts/types/scene"; + +/** + * The main scene interface + */ +const TestScene1: Scene = { + +} + +/** + * The scene to export + */ +export default TestScene1 diff --git a/assets/Scenes/testscene1/someScript.js b/assets/Scenes/testscene1/someScript.js deleted file mode 100644 index c2804e3a..00000000 --- a/assets/Scenes/testscene1/someScript.js +++ /dev/null @@ -1 +0,0 @@ -console.log("Loaded testscene1"); \ No newline at end of file diff --git a/assets/Scripts/client/client.ts b/assets/Scripts/client/client.ts new file mode 100644 index 00000000..f8528595 --- /dev/null +++ b/assets/Scripts/client/client.ts @@ -0,0 +1,22 @@ +import { ClientInventory, onEquipItem, onMoveItemContainer, onUnequipItem } from "/Scripts/client/entity/inventory"; +import { Namespace } from "/Scripts/types/namespace"; + + +/** + * The client namespace type + */ +export interface NamespaceClient extends Namespace { + inventory: ClientInventory, +} + +/** + * The client namespace (should contain all client callbacks, data, etc) + */ +export const Client: NamespaceClient = { + inventory: { + onMoveItemContainer: onMoveItemContainer, + onEquipItem: onEquipItem, + onUnequipItem: onUnequipItem, + }, +} + diff --git a/assets/Scripts/client/entity/inventory.ts b/assets/Scripts/client/entity/inventory.ts new file mode 100644 index 00000000..7038b47e --- /dev/null +++ b/assets/Scripts/client/entity/inventory.ts @@ -0,0 +1,30 @@ + + +/** + * Called every time an item is moved to a container + */ +export const onMoveItemContainer: Array = [ ] + +/** + * Called every time an item is equipped + */ +export const onEquipItem: Array = [ ] + +/** + * Called every time an item is unequipped + */ +export const onUnequipItem: Array = [ ] + +/** + * Called every time the server commands the client to move items to another container + */ +export const onServerMoveItemContainer: Array = [ ] + +/** + * Callbacks that fire every time the player's entity does specific actions + */ +export interface ClientInventory { + onMoveItemContainer: Array, + onEquipItem: Array, + onUnequipItem: Array, +} diff --git a/assets/Scripts/compiler/require_polyfill.js b/assets/Scripts/compiler/require_polyfill.js index 38245780..81bd5951 100644 --- a/assets/Scripts/compiler/require_polyfill.js +++ b/assets/Scripts/compiler/require_polyfill.js @@ -22,6 +22,7 @@ const require = (path) => { return REQUIRE_CACHE[normalizedFilePath].exports } else if(!!COMPILER_fileMap[normalizedFilePath]?.content) { const code = COMPILER_fileMap[normalizedFilePath].moduleContent + loggerScripts.DEBUG('Module code ' + JSON.stringify(code)) let exports = new Function(code)() //create module object const module = { @@ -35,9 +36,12 @@ const require = (path) => { const errorMsg = "FAILED TO REQUIRE FILE " + normalizedFilePath loggerScripts.WARNING(errorMsg) loggerScripts.WARNING('Module value:') - loggerScripts.WARNING(Object.keys(REQUIRE_CACHE?.[normalizedFilePath]) + '') + const cacheValue = REQUIRE_CACHE?.[normalizedFilePath] + loggerScripts.WARNING(Object.keys(cacheValue ? cacheValue : {}) + '') loggerScripts.WARNING('Require cache contents:') loggerScripts.WARNING(Object.keys(REQUIRE_CACHE) + '') + loggerScripts.WARNING('File cache contents:') + loggerScripts.WARNING(Object.keys(COMPILER_fileMap) + '') throw new Error(errorMsg) } } diff --git a/assets/Scripts/engine/engine-init.ts b/assets/Scripts/engine/engine-init.ts index 82ebc045..e28a5445 100644 --- a/assets/Scripts/engine/engine-init.ts +++ b/assets/Scripts/engine/engine-init.ts @@ -1,11 +1,18 @@ -import { Host } from '/engine/engine-interface' -import { loggerScripts } from '/compiler/host_access' +import { Engine } from '/Scripts/engine/engine-interface' +import { loggerScripts } from '/Scripts/compiler/host_access' +import { Client, NamespaceClient } from '/Scripts/client/client' -let host: Host +//the core engine +let engine: Engine /** * Called when the script engine first initializes */ export const ENGINE_onInit = () => { - loggerScripts.INFO('Script Engine Init') + loggerScripts.INFO('Script Engine Beginning Initialization') + + //load namespaces + let client: NamespaceClient = Client + + loggerScripts.INFO('Script Engine Initialized') } diff --git a/assets/Scripts/engine/engine-interface.ts b/assets/Scripts/engine/engine-interface.ts index b265d8fc..1a47844f 100644 --- a/assets/Scripts/engine/engine-interface.ts +++ b/assets/Scripts/engine/engine-interface.ts @@ -3,7 +3,7 @@ /** * The host context that contains all core engine functions */ -export interface Host { +export interface Engine { classes: any, //the host's view of the scripting engine singletons: any, //the singletons available to the script engine } diff --git a/assets/Scripts/types/hook.ts b/assets/Scripts/types/hook.ts new file mode 100644 index 00000000..c327a1dd --- /dev/null +++ b/assets/Scripts/types/hook.ts @@ -0,0 +1,55 @@ +import { Scene } from "/Scripts/types/scene"; + + +/** + * A hook that runs a function when a signal is fired in the engine + */ +export interface Hook { + + /** + * The signal that triggers this hook in particular + */ + signal: any, + + /** + * The function to call when the signal is fired + */ + callback: Function, + +} + +/** + * The scope that the hook is firing from + */ +export enum HookScope { + CORE, + SCRIPT, + SCENE_CLIENT, + SCENE_SERVER, +} + +/** + * A hook that is tracked by the manager + */ +export interface TrackedHook extends Hook { + + /** + * The scope that this hook was defined at + */ + scope: HookScope, + + /** + * The scene that added the hook + */ + scene?: Scene, + +} + +/** + * Manages hooks for the engine + */ +export class HookManager { + + + +} diff --git a/assets/Scripts/types/namespace.ts b/assets/Scripts/types/namespace.ts new file mode 100644 index 00000000..420f8bdc --- /dev/null +++ b/assets/Scripts/types/namespace.ts @@ -0,0 +1,5 @@ + +/** + * A namespace + */ +export type Namespace = Record diff --git a/assets/Scripts/types/scene.ts b/assets/Scripts/types/scene.ts new file mode 100644 index 00000000..71af0fa4 --- /dev/null +++ b/assets/Scripts/types/scene.ts @@ -0,0 +1,44 @@ +import { Hook } from "/Scripts/types/hook"; +import { Namespace } from "/Scripts/types/namespace"; + +/** + * A value that is synchronized between client and server + */ +export function SynchronizedType() { + //called when the synchronized type is evaluated + return function (target: any, propertyKey: string, descriptor: PropertyDescriptor){ + //called when + } +} + +/** + * The namespace of a given scene + */ +export interface Scene extends Namespace { + + /** + * Called when the current instance scene is first loaded + */ + onLoad?: Function + + /** + * Called when the current instance of the scene is unloaded + */ + onUnload?: Function + + /** + * Called when the current instance of the scene is saved -- either periodically or when the scene is being stored to disk + */ + onSave?: Function + + /** + * Values that are synchronized between the client and server. They are also stored to disk when the scene saves + */ + persistentValues?: Record + + /** + * The hooks that are provided by this scene + */ + hooks?: Array + +} diff --git a/docs/src/progress/currenttarget.md b/docs/src/progress/currenttarget.md index b1cca3d5..45e2d885 100644 --- a/docs/src/progress/currenttarget.md +++ b/docs/src/progress/currenttarget.md @@ -1,35 +1,13 @@ - - -Demo experience: - - Load into world - - pick up a katana - - popup appears telling you controls to swing it - - Upon dismissing popup, spawn enemy with sword - - Fight enemy to the death - -Demo requirements: - = Assets = -Fix attack animation bone rotations for hand -Clean up equip state data -Audio FX for everything - - - = Coding = -Sub menu on title screen that allows changing control mappings - - Automatically generate based on the controls arrays in controls handler -Review combat code - - Damage calculation - - Particle generation - - Revive tree -Enemy AI -Ability for private realms to have time start/stop based on the player's feedback <-- sync this up to tutorial ui via script -Scene Message Service - - Can send arbitrary events and messages - - Synchronized and unsynchronized - - Use synchronized to have client-driver ui interactions - - Variables - - Synchronized and unsynchronized - - - - \ No newline at end of file ++ spawn into the world ++ there is a sword lying on the ground ++ when you grab the sword, a tutorial popup appears to tell you how to use in + fire a script on a hook + hook for grabbing an item ++ on clearing the tutorial, continue the game+ when the sword is equipped, create another popup to teach sword controls. it pauses the game + hook on equipping an item + script ability to pause and unpause game ++ when popup is accepted, spawn an rnemy with an effect + enemy ai + review effects + review combat code (lifestate, damage calculation, etc) + audio fx for everything diff --git a/src/main/java/electrosphere/script/ScriptEngine.java b/src/main/java/electrosphere/script/ScriptEngine.java index eaa8801c..4b44e01f 100644 --- a/src/main/java/electrosphere/script/ScriptEngine.java +++ b/src/main/java/electrosphere/script/ScriptEngine.java @@ -22,6 +22,11 @@ import electrosphere.util.MathUtils; */ public class ScriptEngine { + //the default namespaces for + public static String SCRIPT_NAMESPACE_ENGINE = "engine"; //namespace for the engine functions exposed to the script engine + public static String SCRIPT_NAMESPACE_SCRIPT = "script"; //namespace for the core typescript functionsw + public static String SCRIPT_NAMESPACE_SCENE = "scene"; //namespace for the current scene + //the graal context Context context; @@ -51,6 +56,12 @@ public class ScriptEngine { "Scripts/compiler/host_access.js", }; + //folders that should be loaded once we have bootstrapped the compiler + static final String[] foldersToLoadOnInit = new String[]{ + "Scripts/engine", + "Scripts/client", + }; + //The classes that will be provided to the scripting engine //https://stackoverflow.com/a/65942034 static final Object[][] staticClasses = new Object[][]{ @@ -92,7 +103,9 @@ public class ScriptEngine { defineHostMembers(); //register engine files - registerScriptDirectory("Scripts/engine",FileUtils.getAssetFile("Scripts/engine")); + for(String folderToRegister : foldersToLoadOnInit){ + registerScriptDirectory(folderToRegister,FileUtils.getAssetFile(folderToRegister)); + } //compile compile(); diff --git a/tsconfig.json b/tsconfig.json index 703c8288..6c0d8462 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "paths" : { "/*" : [ - "./assets/Scripts/*" + "./assets/*" ], } }