diff --git a/game-engine/game-engine.md b/game-engine/game-engine.md index fa85d0b..eb5b2bc 100644 --- a/game-engine/game-engine.md +++ b/game-engine/game-engine.md @@ -6,43 +6,50 @@ The game engine is incomplete and still evolving, as such this page should be co The Toy programming langauge was designed from the beginning as an embedded scripting language for some kind of game engine. Different iterations have existed with different implementations, some of which could charitably be said to function. The current version, and the most stable and feature complete so far, has reached a point where it needs some kind of concrete engine to improve any further. -Currently, the engine exists under the `Box/` directory within the "airport" repository, and builds as part of that program - this will be packaged as a separate repo soon. +Currently, the engine exists within its own repository, which can be found here: -[https://github.com/Ratstail91/airport](https://github.com/Ratstail91/airport) - -NOTE: This documentation page is a rushjob, and will be expanded into it's own subsection eventually. +[https://github.com/Ratstail91/Box](https://github.com/Ratstail91/Box) ## Engine Structure -The engine is invoked with just three lifecycle functions called directly from `main()`: +The engine's APIs depend heavily on Toy's drive system, so that must be initialized at the beginning of the `main()` function. + +The engine proper is invoked with just three lifecycle functions`: ```c -#define SDL_MAIN_HANDLED - #include "box_engine.h" int main(int argc, char* argv[]) { - //the real main() has some extra junk, but this is all that's needed for the engine - Box_initEngine(); + //initialize the drive system + Toy_initDriveSystem(); + Toy_setDrivePath("scripts", "assets/scripts"); + + //invoke the engine + Box_initEngine("scripts:/init.toy"); //passing in the specified init file Box_execEngine(); Box_freeEngine(); + + //clean up the drive system when you're done + Toy_freeDriveSystem(); + return 0; } + ``` The engine proper holds the following elements: -* SDL2 window and renderer +* SDL2 video and audio elements * Framerate controls * Toy interpreter * Input keyboard mapping dictionaries * The root node -Input and rendering in the game engine are handled by SDL2 - this allows for the game to, in theory, be built on multiple platforms. For the time being, however, we're just targeting Windows due to a lack of testing machines. +Video and audio in the game engine are handled by SDL2 and SDL2_mixer - this allows for the game to, in theory, be built on multiple platforms. For the time being, however, we're just targeting Windows due to a lack of testing machines. The engine is calibrated to run at 60 FPS - if the "simulation time" falls too far behind the real time, then frame rendering is skipped in favour of speeding up the game logic. Likewise, if the simulation time runs too fast, then the simulation step is skipped instead and an extra frame is drawn. This process can lead to multiple skips in a row, in both directions. -The Toy interpreter is the core of the scripting system. Other interpreters may be generated and cleared during Toy's internal processes, but this one lasts for the duration of the program. +The engine's interpreter is the core of the scripting system. Other interpreters may be generated and cleared during Toy's internal processes, but this one lasts for the duration of the program. The keyboard inputs can be remapped using API functions - these mappings are stored and accessed within a pair of Toy dictionaries that have simply been embedded directly into the engine for easy access. @@ -50,7 +57,7 @@ The nodes form a deep tree-like structure, with the "root node" at it's base. ## Node Structure -The fundemental building block of the engine's logic is the node - nodes can represent anything within the game world, from entities to abstract global systems. You can think of entities as having a 1:1 mapping to Toy scripts, as each one is given bytecode on initialization that fills its internals. +The fundemental building block of the engine's logic is the node structure - nodes can represent anything within the game world, from entities to abstract global systems. You can think of entities as having a 1:1 mapping to Toy scripts, as each one is given bytecode on initialization that populates its internals (external libraries like the runner library are still possible). A node holds the following elements: @@ -58,8 +65,9 @@ A node holds the following elements: * An array of references to its children, and bookkeeping variables for tracking them * A dictionary of functions defined in the Toy script * A single SDL texture reference, and controls for rendering it (including as an animated spritesheet) +* Position, motion and scale values -The nodes are deeply integrated with Toy scripts, while Toy was written specifically for this purpose. The tree-like structure of the nodes all exist entirely within the computer's heap memory as a result of Toy's memory model - this comes with performance drawbacks and cleanup requirements. Child nodes should never be referenced directly, as they may be `NULL` references that have been released - the internal array doesn't shrink, and the tombstones don't get reused. +The nodes are deeply integrated with Toy scripts, while Toy was written specifically for this purpose. The tree-like structure of the nodes all exist entirely within the computer's heap memory as a result of Toy's memory model - this comes with performance drawbacks and cleanup requirements. Child nodes should never be referenced directly, as they may be `NULL` references that have been released, but not yet pruned. The rules of execution for scripts and functions is as follows: @@ -76,6 +84,9 @@ The following functions, which are defined within the node scripts, are invoked * `onLoad(node: opaque)` * `onInit(node: opaque)` +* `onFrameStart(node: opaque)` +* `onUpdate(node: opaque, delta: int)` +* `onFrameEnd(node: opaque)` * `onStep(node: opaque)` * `onFree(node: opaque)` * `onDraw(node: opaque)` @@ -86,7 +97,7 @@ The following functions, which are defined within the node scripts, are invoked * `onMouseButtonUp(node: opaque, x: int, y: int, button: string)` * `onMouseWheel(node: opaque, xrel: int, yrel: int)` -These may change or expand as more input devices are added, and the engine matures. +(These may change or expand as more input devices are added, and the engine matures.) NOTE: `onLoad()` is invoked every time a node is loaded - but `onInit()` is only invoked once by the engine. After that, `initNode()` must be called manually on any node children that are loaded later. @@ -94,38 +105,11 @@ NOTE: `onLoad()` is invoked every time a node is loaded - but `onInit()` is only A series of libraries are provided to allow Toy to interface and control the engine. In addition, the libraries stored within Toy's `repl/` directory are also available (see the main page for the list). -During startup, the script named `init.toy` in the root of the scripts directory is executed. This file can be used to configure input mappings, as well as initializing the window and node tree. +During startup, the script named `init.toy` in the the assets/scripts directory is executed. This file can be used to configure input mappings, as well as initializing the window and node tree. -TODO: Complete the rest of this page +* Engine Library +* Node Library +* Input Library +* Music Library +* Sound Library -# Engine API - -The engine API is for controlling the core of the engine directly. - -## initWindow(caption: string, width: int, height: int, fullscreen: bool) - -This function initializes the game's window, as well as specifying it's dimensions and properties. There is only one window - calling this multiple times is a fatal error. Also, the game's loop will simply not run if the window hasn't been initialized. - -## loadRootNode(fname: string) - -TODO - -## getRootNode(): opaque - -TODO - -# Node API - -The node API is for controlling individual nodes. - -TODO - -# Input API - -The input API is for mapping different interface devices to different "event" names - currently only the keyboard inputs can be mapped this way, but more devices may be added in the future - thus, the input API was separated into a separate library from the engine proper. - -TODO - -# Box C API - -TODO \ No newline at end of file diff --git a/index.md b/index.md index fc4e46f..451d794 100644 --- a/index.md +++ b/index.md @@ -80,6 +80,12 @@ print tally(); //3 ## Game Engine -Note: This section is incomplete. +Note: This section is WIP. * [Game Engine](game-engine/game-engine.md) +* Engine Library +* Node Library +* Input Library +* Music Library +* Sound Library +