# How to Work the Trial ## 1. Introduction This is a tutorial on how to get going with Trial game engine by [Shinmera](https://shinmera.com) using Common Lisp. I long have had trouble getting to work on various projects and started writing this to teach myself as well as any others who come after. This tutorial assumes that you have understanding of how to use the Common Lisp language, know how to create your own Lisp projects, and know how to manage quicklisp package manager. If you wish to learn to program in Common Lisp I highly recommend [Practical Common Lisp](https://gigamonkeys.com/book/) available online for free and for purchase in a book form. It is absolutely excellent to learn from. I will also be using [emacs on MSYS2](https://packages.msys2.org/package/mingw-w64-x86_64-emacs) with a modified version of [shinmera's emacs configurations](https://github.com/shinmera/.emacs) as my environment and [SBCL](https://www.sbcl.org) as my Common Lisp compiler on Windows. All this works much better on Linux but this is what I'm currently used to. Much of this tutorial is inspired and based on the work of [Sheepolution on their LÖVE 2D tutorial](https://sheepolution.com/learn/book/contents). The main difference is that this tutorial will not be teaching you how to program as I am in no way someone who can answer complicated questions on the subject if such arise. Much like LÖVE mentioned above Trial is a framework without a graphical user interface. A pencil and a notepad are great friends for any visual thinking and planning you might need to do. The only fully featured a 2D graphical level editor used in Trial [can be found in the game Kandria.](https://kandria.com/editor) You can find [the documentation for Trial itself here](https://shirakumo.github.io/trial/index.html) and [a how to get started guide here](https://shirakumo.github.io/trial/start.html). I recommend you go through that last one before continuing. ### Summary and Goals of This Tutorial As you progress through this tutorial you will be making a few small games that teach you how to react to user inputs, manage your assets, and other necessities for an interactive video game. Below are images of the full products you'll be creating along with me. TODO: Add images. ## 2. Trial As mentioned before, Trial lacks a graphical user interface to work with the engine. It is very modular with a multitude of different systems you have to load in separate. I will not be delving into the depths of its source code but the links in the introduction should lead you that way if you are curious. It is, of course, open source so you may pull the latest version of it from [Trial's Github page](https://github.com/shirakumo/trial). ### How Does It Work? Trial uses an event-loop system(1) and a scene manager that you give your handlers and entities of you game. Much of it uses Common Lisp Object System (CLOS) to stay organised, which is quite powerful and intuitive in my humble opinion. Trial is also able to make use of multiple different rendering backends, but we'll be using the one for OpenGL Shading Language (GLSL). Trial constructs shaders for it mostly automatically depending on what entity classes you build upon.(2) We won't need to get into its details as everything we need for the tutorial is already ready within the engine to use with minimal fuss. Besides the backends there is a multitude of different modules we'll also have to load. The two mentioned in the Getting Started Guide I linked in the introduction were `TRIAL-GLFW` and `TRIAL-PNG`. We'll only need these two for starters. Beyond this I hope to use `HARMONY` audio system and `TRIAL-ALLOY` module for the interactive user interface later. I will get into them once they become relevant to the tutorial. For printing into the console log output we are using `VERBOSE` which Trial always loads in. Footnote 1: A more detailed synopsis on the event-loop system can be found in [the official documentation](https://shirakumo.github.io/trial/event-loop.html). Footnote 2: I am purposefully simplifying this description but you can read more on the render pipeline in [Trial's documentation](https://shirakumo.github.io/trial/render-pipeline.html). ## 3. Creating Something That Moves Currently we should have a very basic main file from the Getting Started Guide. ```lisp (in-package #:org.my.project) (defclass main (trial:main) ()) (progn (defmethod setup-scene ((main main) scene) (enter (make-instance 'vertex-entity :vertex-array (// 'trial 'unit-cube)) scene) (enter (make-instance 'sidescroll-camera :zoom 100.0) scene) (enter (make-instance 'render-pass) scene)) (maybe-reload-scene)) (defun launch (&rest args) (apply #'trial:launch 'main args)) ``` **NOTE:** On the Getting Started Guide it had you use the `3D-CAMERA`. I have changed that to `SIDESCROLL-CAMERA` for the tutorial that has the zoom of 100.0 for now. The other two files, my-project.asd and package.lisp, are unchanged. TODO: Add an image of Trial screen with a white cube. Now, the different parts here. The `MAIN` class you define is the main game container of everything that it has in it at that moment. It and `LAUNCH` symbols are shadowed by the package definition(3). Most importantly `MAIN` class handles the render contexts for us. You can think of it as your window for your game. The second part that you'll see is the `SETUP-SCENE` method for the `MAIN` class. This is what is called at the very beginning as you launch the game. Here it creates anything that you have on the scene graph, which for now are the cube, the camera, and the `RENDER-PASS` which draws things on the screen. Much of this system is handled by containers which hold entities and/or other containers. We won't need more than the basic `SCENE` container for now that we `ENTER` objects into. The `MAYBE-RELOAD-SCENE` is there as a helper so that when you make any changes you simply recompile the `PROGN` group and everything gets reloaded into your game window without needing relaunch. ### Let's Make That Cube Move Now, the vertex entities are rather unwieldy for our purposes so we will eventually get rid of that but I do want to leave the sprite system for a later chapter when we are more used to Trial's flow. So let's make that little cube do things. First we'll need the cube to be an actual entity of its own capable of listening to events and add that into the scene. ```lisp (define-shader-entity my-cube (vertex-entity colored-entity scaled-entity transformed-entity listener) ((vertex-array :initform (// 'trial 'unit-cube)) (scaling :initform (vec 100 100 100)) (color :initform (vec 0.96 0.66 0.72 1)))) (define-handler (my-cube tick) (tt dt) (let ((speed 1.0)) (setf (orientation my-cube) (qfrom-angle +vz+ (* speed tt))) (setf (vx (location my-cube)) (* 400.0 (sin (* speed tt)))))) (progn (defmethod setup-scene ((main main) scene) (enter (make-instance 'my-cube) scene) (enter (make-instance 'sidescroll-camera :zoom 1.0) scene) (enter (make-instance 'render-pass) scene)) (maybe-reload-scene)) ``` Here `DEFINE-SHADER-ENTITY` creates a `MY-CUBE` entity class with the information that it holds vertex data, it is coloured with a hue, it is transformed so that it might change location and rotation, and that it is an event listener. * `VERTEX-ENTITY` we already know from earlier — it has the vertex data of a unit cube. * `COLORED-ENTITY` makes sure to paint it something nicer than pure white. * Set the colours as you like, I enjoy the pink hue. * `SCALED-ENTITY` to make the cube bigger rather than us having to zoom in closer. * `TRANSFORMED-ENTITY` ensures that there is location and rotation data which we can manipulate. * `LISTENER` allows us to listen to the `TICK` event, as well as other events later on. * The `TT` variable is the time in seconds that has passed since the start. * The `DT` variable is the time in seconds since the tick event.(4) * Try changing the numerical values there or even make the speed increase over time. So we also created a tick-event handler. I kept it rather simple here. The first part sets the orientation of the cube to rotate counter-clockwise on the screen. The second line makes it move left and right repeatedly as time goes on. We will eventually add more handlers. Finally we also changed the scene to get our new and fancy cube. Note that since we made the cube into a `SCALED-ENTITY` the camera zoom level may be returned to 1.0. Feel free to play around with the tick-event and changing that speed variable to different values to see how it affects the cube's movement. You may also note that we didn't make movement relative to the size of the window, we'll eventually have to take that into account as well but that's a worry for our future selves. TODO: Add an animated image. Footnote 3: You may recall from that file that we are using `#:CL+TRIAL` package rather than both of `#:CL` and `#:TRIAL` packages separate from each other. It does some important definitions that would otherwise clash. Footnote 4: You may have received a warning on that the `DT` variable is unused. The time variables are optional to include to the handler. The time unit is in seconds and it's usually something like 0.01. It is normally used to ensure that movement happens at a set pace rather than whatever the frames-per-second might be. We simply did not need it this time as the movement is looped, but we'll definitely need it in near future. ## 4. Keymapping and Input Handling TODO: