• Docs
  • Install
  • Follow @cosplayengine
  • v.0.9.5
  • GitHub
  • Watch
  • Examples
  1. Home
  2. Game Structure

Game Structure

  • Introduction
  • Install
  • ASCII Games
  • Demos
  • Examples
  • Macarena
  • Pong
  • Snake
  • Bird
  • Developer Guide
  • Quick Game 🏃
  • Key Concepts
  • Game Structure
  • Scenes & Objects
  • Log & Debugging
  • Pixels & Colors
  • Images
  • Keyboard Input
  • Sprite Animation
  • Shaders
  • Particle Effects
  • Fonts
  • Canvas Drawing
  • Text Input
  • Camera Tracking
  • Tile Mapping
  • Audio
  • Video
  • UI Toolkit
  • Build & Run

Game Structure

CosPlay game is nothing more than a standard Scala3-based program. In fact, CosPlay imposes absolutely minimum requirements on overall ceremony and code organization. There are only a couple of methods that need to be called to initialize the game engine, start the game loop and dispose the game engine when the game exists. Note that built-in examples provide great illustration on game organization.

CosPlay provided two sets of methods to manage the game's lifecycle:

  • First set uses classic exception-based handling.
  • Another set uses Try-monad for composable effect-based error handling.

While you can choose either way the effect-based error handling forces a more rigorous error handling requiring to handle errors at each call. Note that you can't mix these two approaches. Below are two examples of these two approaches to error handing for game's lifecycle management:

Exceptions Try-Monad
                    import org.cosplay.*

                    object Game:
                        def main(args: Array[String]): Unit =
                            // Initialize the engine.
                            CPEngine.init(
                                 CPGameInfo(name = "My Game"),
                                 System.console() == null || args.contains("emuterm")
                            )

                            // Create game scenes & their scene objects.
                            val sc1 = new CPScene(...)
                            val sc2 = new CPScene(...)

                            // Start the game & wait for exit.
                            try CPEngine.startGame(sc1, sc2)
                            finally CPEngine.dispose()

                            sys.exit(0)
                

NOTES:

  • Although not a requirement, it is recommended to use main(...) method (line 4) as an entry point to the game application. It provides compatibility with the standard Java runtime.
  • Before you can use CosPlay game engine you need to initialize it by calling CPEngine.init(...) method (line 6). See CPEngine object for API details.
  • Note the line 8: System.console() == null || args.contains("emuterm"). This is an idiomatic way to check whether the game is running in a native ANSI terminal or in the built-in terminal emulator. This allows user to pass emuterm command line parameter to force the built-in terminal emulator if for some reason the native ANSI terminal is detected but does not work properly.
  • After the game engine is initialized but before you start the game you need to create your initial scenes, scene objects, assets or anything else (lines 12-13) your game may need to start. Note that you can add new and remove existing scenes, scene object, assets, etc. at any point of the game later on. In fact, game can choose different strategies of either pre-creating all necessary resources upfront or create them as needed on the fly - but at least one initial scene must be created before the game can start.
  • Once at least one scene is ready - you can start the game by calling CPEngine.startGame(...) method (line 16). As always, see CPEngine object for API details. It is a good practice to wrap this call into try-finally clause and call CPEngine.dispose() in the finally clause (line 17).
                    import org.cosplay.*

                    object Game:
                        def main(args: Array[String]): Unit =
                            // Initialize the engine.
                            CPEngine.initEff(
                                 CPGameInfo(name = "My Game"),
                                 System.console() == null || args.contains("emuterm")
                            ).recover(_ => sys.exit(1))

                            // Create game scenes & their scene objects.
                            val sc1 = new CPScene(...)
                            val sc2 = new CPScene(...)

                            // Start the game & wait for exit.
                            CPEngine.startGameEff(sc1, sc2).recover(_ => sys.exit(2))
                            // Dispose the engine.
                            CPEngine.disposeEff().fold(_ => sys.exit(3), _ => sys.exit(0))
                

NOTES:

  • Notice that effect-based error handling forces us to handle error at each step supplying specific error handling (in this example exiting process with appropriate exit code).
  • Although not a requirement, it is recommended to use main(...) method (line 4) as an entry point to the game application. It provides compatibility with the standard Java runtime.
  • Before you can use CosPlay game engine you need to initialize it by calling CPEngine.initEff(...) method (line 6). See CPEngine object for API details.
  • Note the line 8: System.console() == null || args.contains("emuterm"). This is an idiomatic way to check whether the game is running in a native ANSI terminal or in the built-in terminal emulator. This allows user to pass emuterm command line parameter to force the built-in terminal emulator if for some reason the native ANSI terminal is detected but does not work properly.
  • After the game engine is initialized but before you start the game you need to create your initial scenes, scene objects, assets or anything else (lines 12-13) your game may need to start. Note that you can add new and remove existing scenes, scene object, assets, etc. at any point of the game later on. In fact, game can choose different strategies of either pre-creating all necessary resources upfront or create them as needed on the fly - but at least one initial scene must be created before the game can start.
  • Once at least one scene is ready - you can start the game by calling CPEngine.startGameEff(...) method (line 16). As always, see CPEngine object for API details. Upon exit from the game loop we call CPEngine.disposeEff().

That's it! 👌

Game Engine

In-Game Shortcuts

While in game you can use the following reserved keyboard shortcuts. Note that these keys are NOT available to the game itself as they are intercepted and processed by the game engine itself:

  • Ctrl+Q - to toggle in-game FPS overlay.
  • Ctrl+L - to open GUI-based log viewer & debugger.
  • F12 - to take the screenshot in REXPaint *.xp format saved in the current folder.

As we have seen in the game organization section above the CosPlay game engine is defined by CPEngine object. Game engine is mostly an internal object, and it is only used at the beginning of the game. It provides variety of utility and miscellaneous methods for the games (see scaladoc for API details):

  • Start and stop games.
  • Pause and resume games.
  • Programmatically open the log viewer.
  • Programmatically debug games using step-through.
  • Register additional input devices like gamepads and joysticks.
  • Manage rendering statistics.

System Properties

There are number of JVM system properties that control various aspects of the game engine operation. Note that these properties must be set - in the command line, in the launch script, or in the game itself - before method CPEngine.init(...) is called:

System PropertyValue TypeDescription
COSPLAY_GAME_IDString Internal game ID.
COSPLAY_EMUTERM_FONT_NAMEString Applies to the built-in terminal emulator only. Specifies the font name to use.
COSPLAY_EMUTERM_FONT_SIZEInt Applies to the built-in terminal emulator only. Specifies the font size to use.
COSPLAY_EMUTERM_CH_WIDTH_OFFSETInt Applies to the built-in terminal emulator only. Specifies character width offset. Can be positive or negative. Default is 0.
COSPLAY_EMUTERM_CH_HEIGHT_OFFSETInt Applies to the built-in terminal emulator only. Specifies character height offset. Can be positive or negative. Default is 0.
COSPLAY_EMUTERM_ANTIALIASBoolean Applies to the built-in terminal emulator only. If system property is present - the font rendering will use antialiasing. By default, no antialiasing is used.
COSPLAY_FORCE_8BIT_COLORBoolean Forces the automatic conversion from 24-bit color to 8-bit color. Only needed when running in the native terminal that does not support 24-bit color. Default value is false.
COSPLAY_TERM_CLASSNAMEString Fully qualified class name for the custom terminal emulator implementation. Class must implement CPTerminal trait.
  • On This Page
  • Game Structure
  • Game Engine
  • System Properties
  • In-Game Shortcuts
  • Ctrl+Q FPS Overlay
  • Ctrl+L GUI Debugger
  • F12 REXPaint Screenshot
  • Quick Links
  • Discord
  • Stack Overflow
  • GitHub
  • @cosplayengine
  • YouTube
  • API
Copyright © 2023 Rowan Games, Inc. Privacy • Docs release: 0.9.5 Latest: