Petra Engine Source Code ======================== 1. About 2. Building 3. Quick Start 4. Documentation 1. About -------- This is the source code for the Petra Engine, a 3D game engine for retro PC systems (mainly DOS but also Win9x), originally written for the 2020 MS-DOS Game Jam #2 game "Post Apocalyptic Petra" (hence the name) but later ported to other systems. This version of the engine has been extracted from the original game's source code (specifically, version 0.99o) with -almost- all game-specific code removed. A very simple game template with the minimum required assets has replaced the Post Apocalyptic Petra code. A script to create a new project directory alongside the engine directory is provided too. 2. Building ----------- The engine needs game-specific source units to build and work. A simple example game ("Petra Engine Template Game") is provided that can be used as a starting point. Building the engine is basically about building a game that uses the engine. To build the game, you need to install Free Pascal. For most targets (DOS, Linux, etc) the latest version will do, but if you want to target retro Win9x PCs you need to download Free Pascal 2.2.4 (FPC 2.2.4 and whatever is the latest version can be installed alongside each other). The fpc binary must also be available at the PATH (e.g. running fpc -h from a command-line window should show the Free Pascal help screen). Obviously you also need any cross-compilers for the targets you want (if you are not building it for the OS you are running Free Pascal at). Note that if you are targeting go32v2 (i.e. DOS) and using Windows then you can simply extract the unit files from the DOS distribution of Free Pascal since the Windows utilities can also work with the DOS utilities (this is not the case for other OSes though). To build the editor you also need to install Lazarus (FPC is part of Lazarus for the Windows version but it is recommended to also install a standalone version). Since the editor needs to be build against the game-specific code (and is the recommended IDE for editing it) you should install it anyway. Note that under Linux you almost always want to install Lazarus from source code (i.e. download the source code, extract it to a directory, enter it and type 'make bigide' inside it - then install any missing libraries, like the gtk2 development files, etc that the linker complains about) since the versions available from repositories tend to often not work correctly. You can install Free Pascal from Linux repositories without issues though. There are two ways to decide where and how to build the game: 1. Build the game inside the engine's directory - this is easiest and allows for modifying the engine itself for each game 2. Use new-game.sh from the Scripts directory to make a new directory with only the game code and data that references the engine's directory - this allows for the engine code to be shared between different games Either way you also need to have a GNU Bash shell available running as a native application (i.e. no VM and no WSL if you use Windows). Unix-based OSes (i've only tried Linux but should work with macOS too) already come with GNU Bash preinstalled. For Windows you can use MSYS2 or Cygwin. To use the new-game.sh script you must run it from the same directory that contains the PetraEngine directory - e.g. if you uncompressed the engine's ZIP file to ~/Code (or C:\Code) and thus have a ~/Code/PetraEngine (or C:\Code\PetraEngine) directory, then you must run the script from ~/Code (or C:\Code) like this ($ is the Bash prompt): $ PetraEngine/Scripts/new-game.sh MyGameName (replace MyGameName with the name of the directory to put the new game - the directory must not exist, otherwise the script will display an error) For either approach, you will have a script named build.sh in the game (or engine's) source directory. You may want to edit this build.sh file to point at the paths where FPC 2.2.4 and Lazarus' lazbuild tools are installed for building the Win32 versions and editor respectively. Strictly speaking this is not required unless you want to build the standalone Windows versions and/or the editor from the command line - otherwise you can just ignore the standalone Windows versions (if you are only targeting DOS or one of the other non-Win32 platforms) and open (and run) the editor project file from inside Lazarus. To run build.sh simply do a... $ ./build.sh ...from inside the game source directory. This will display the available targets, which should include -among others- the dos, sdl and gdi targets that should require no additional dependencies than what is available out of the box by Free Pascal. So, to build the DOS version you need to enter: $ ./build.sh dos The DOS version of the game will be build as pgame.exe inside the Build subdirectory (which will be created if it doesn't exist). Note that the "pgame" part is a common name that will be used for each target with target-specific prefixes and suffixes (e.g. the SDL software rendering target is called sdlpgame and the DirectDraw target is called winpgame.exe). You can modify the exe= line in build.sh to use a different name. Similarly to build the SDL version you type: $ ./build.sh sdl The SDL version should build and run under most OSes and can be used for development testing purposes (though running the game from inside the editor is also possible). The template game assumes all data are stored under the GameData directory under the current directory, so you need to run it like: $ Build/sdlpgame This is also important for the editor: if you build it using the ./build.sh script (by entering ./build.sh editor) you need to run it like $ Build/editor so that it can find the data. If you open the editor.lpi file from Lazarus you also must set the working directory from Run -> Run Parameters to be the game's (or engine's) own directory instead of the GameSrc subdirectory (where the game sources are located), otherwise the editor will not find the data and throw various exceptions. If you get something like a Range check error or errors about failing to load files then you tried to run the editor from some other directory. Some utilities are also provided for creating PAK files (can contain all assets in a single file which can help a bit with ZIP compression) and converting between palette and image files. To build those use: $ ./build.sh utils The utilities will be under the Build directory like the game and editor. 3. Quick Start -------------- Once you have the game and the editor binaries build you can run the editor and open the map1.map file from the GameData directory. This opens some default map with a single grid (the world is made up of grids - you do not really *have* to use the grids, you could write your own logic for making the scene, but the engine can use the grids to generate sectors and portals and provides some very simple checks against the grids for collisions), a light and a TPlayer entity that represents the player character (again, not necessary, but a common and useful starting point). Press F9 to enter in Play mode. The camera will move at the player's position and... you can't do much from there. Press F9 to exit Play mode. When entering Play mode the engine creates a deep copy of the TGame object instance, swaps the new copy with the previous game instance (which is kept around to be swapped again when exiting Play mode) and enters in "game mode", allowing the game logic to run. Exiting Play mode simply deletes that copy and restores the original instance. Maps (levels) are basically serialized TWorld objects, which contain serialized TEntity (and subclasses) objects. To create a new object type you subclass TEntity and register it with a call to RegisterSerializableClass from the unit's initialization section. The template game already registers a TPlayer class in the EPlayer.pas unit that provides some example code that can be used as a starting point. The engine also provides some other common entity classes like TLight, which provides a light source that is used to calculate static lighting for grids, TStaticMeshEntity that can be used to render a static mesh, TSoundEmitter that is emitting a sound in 3D space, etc. The TPlayer class that is part of the template game is a TSceneNodeEntity subclass - that is an entity that is represented in the game via a scene node (a TSceneNode subclass, itself providing functionality to render things - e.g. by overriding the RenderNode method). The scene node is created in the CreateSceneNode method (though in the example it does nothing nor is the scene node itself used). This can be a starting point for when the game uses some 3rd person perspective - for 1st person games the class can be changed to TEntity and the CreateSceneNode method be deleted. The TPlayer class also implements the TInputHandler interface and when the entity is added to the world (notified by the AddedToWorld method), it registers itself with the input driver so that it can handle key and mouse events. Some other methods that the TPlayer overrides (though it only uses them as placeholders for games to expand on) are: RemovedFromWorld (the opposite of AddedToWorld, which is called when the entity is removed from the world), AddSceneNodes/RemoveSceneNodes (added to add any previously created scene nodes - strictly speaking you do not need to override this for TSceneNodeEntity subclasses since TSceneNodeEntity will add the node created via CreateSceneNode to the scene for you), Update (called at a fixed rate), Frame (called for every frame) and PerformCommand (called whenever a script wants to perform a command on an entity - usually via the "send [target] [command]" command). 4. Documentation ---------------- There isn't really any guide-like documentation (or even reference for that matter) for the engine. The source code however is thoroughly commented and every class and method has a comment above it giving it a brief description which the Lazarus IDE will display in a popup when hovering the mouse or during auto-completion, which can help as a simple API reference. Documentation for the editor and scripts are not (yet) available, you can try to play around with the editor and perhaps download Post Apocalyptic Petra with the editor and play with that too (checking the scripts, etc). You can also check a ~3h video of making a map for Post Apocalyptic Petra which shows some functionality and using the editor: https://www.youtube.com/watch?v=a0nisHz424A Kostas "Bad Sector" Michalopoulos badsector@runtimeterror.com You may find the latest version of the engine at http://runtimeterror.com/tech/petra