A game engine for playing and creating your own RPG games
This repository has been archived on 2023-06-24. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
Find a file
2022-12-21 14:49:42 +01:00
.vscode #11 Start proper report 2022-12-21 13:37:38 +01:00
assets #1 Rendering of level 2022-12-21 00:04:49 +01:00
levels Correct level3! 2022-11-22 20:14:52 +01:00
lib #3 Restrict player going places 2022-12-21 14:49:42 +01:00
src Ready for takeoff 2022-12-13 23:21:51 +01:00
test #18 Started conversion to Game 2022-12-20 19:53:40 +01:00
.gitignore Added VSCode config 2022-12-14 21:20:21 +01:00
header.yaml #11 Start proper report 2022-12-21 13:37:38 +01:00
LICENSE Initial commit 2022-11-22 20:01:41 +01:00
README.md #11 Start proper report 2022-12-21 13:37:38 +01:00
rpg-engine.cabal #3 Restrict player going places 2022-12-21 14:49:42 +01:00
stack.yaml #18 & massive structure overhaul 2022-12-19 22:54:42 +01:00
verslag.pdf #11 Start proper report 2022-12-21 13:37:38 +01:00

RPG-Engine

RPG-Engine is a game engine for playing and creating your own RPG games.

If you are interested in the development side of things, development notes can be found here.

This README serves as both documentation and project report, so excuse the details that might not be important for the average user.

Playing the game

These are the keybinds in the game. All other keybinds in the menus should be straightforward.

Action Primary Secondary
Move up Arrow Up w
Move left Arrow Left a
Move down Arrow Down s
Move right Arrow Right d

Example playthrough

TODO

  • An example playthrough, with pictures and explanations

\pagebreak

Writing your own stages

A stage description file, conventionally named <stage_name>.txt is a file with a JSON-like format. It is used to describe everything inside a single stage of your game, including anything related to the player, the levels your game contains and what happens in that level. It is essentially the raw representation of the initial state of a single game.

Note: At the moment, every game has a single stage description file. Chaining several files together is not possible yet.

A stage description file consists of several elements.

Element Short description
Block optionally surrounded by { ... }, consists of several Entry's, optionally separated by commas ,
Entry is a Key - Value pair, optionally separated by a colon :
Key is a unique, predefined String describing Value
Value is either a Block or a BlockList or a traditional value, such as String or Int
BlockList is a number of Block's, surrounded by [ ... ], separated by commas, can be empty
We'll look at the following example to explain these concepts.
player: {
    hp: 50,
    inventory: [
        {
            id: "dagger",
            x: 0,
            y: 0,
            name: "Dagger",
            description: "Basic dagger you found somewhere",
            useTimes: infinite,
            value: 10,

            actions: {}
        }
    ]
}

levels: [
    {
        layout: {
            | * * * * * *
            | * s . . e *
            | * * * * * *
        },
        items: [],
        entities: []
    },
    {
        layout: {
            | * * * * * * * *
            | * s . . . . e *
            | * * * * * * * *
        },
        items: [
            {
                id: "key",
                x: 3,
                y: 1,
                name: "Door key",
                description: "Unlocks a secret door",
                useTimes: 1,
                value: 0,
                actions: {
                    [not(inventoryFull())] retrieveItem(key),
                    [] leave()
                }
            }
        ],
        entities: [
            {
                id: "door",
                x: 4,
                y: 1,
                name: "Secret door",
                description: "This secret door can only be opened with a key",
                direction: left,
                actions: {
                    [inventoryContains(key)] useItem(key),
                    [] leave()
                }
            }
        ]
    }
]

This stage description file consists of a single Block. A stage description file always does. This top level Block contains two Values player and levels, not separated by commas.

player describes a Block that represents the player of the game. Its Entrys are hp (a traditional value) and inventory (a BlockList of several other Blocks). They are both separated by commas this time. It is possible for the inventory to be an empty list [].

levels is a BlockList that contains all the information to construct your game.

layout syntax

If Key has the value layout, Value is none of the types discussed so far. Instead Layout is specifically made to describe the layout of a level. This object is surrounded by { ... } and consists of multiple lines, starting with a vertical line | and several characters of the following:

  • x is an empty tile a.k.a. void.
  • . is a tile walkable by the player.
  • * is a tile not walkable by the player.
  • s is the starting position of the player.
  • e is the exit.

All characters are interspersed with spaces.

actions syntax

If Key has the value actions, the following changes are important for its Value, which in this case is a Block with zero or more Entrys like so:

  • Key has type ConditionList.

    A ConditionList consists of several Conditions, surrounded by [ ... ], separated by commas. A ConditionList can be empty. If so, the conditional is always fulfilled.

    A Condition is one of the following:

    • inventoryFull(): the players inventory is full.
    • inventoryContains(objectId): the players inventory contains an object with id objectId.
    • not(condition): logical negation of condition.
  • Value is an Action.

    An Action is one of the following:

    • leave()
    • retrieveItem(objectId)
    • useItem(objectId)
    • decreaseHp(entityId, objectId)
    • increasePlayerHp(objectId)

Back to the example

If we look at the example, all the objects are

>Block<
    Entry = Key ('player') + >Block<
        Entry = Key ('hp') + Value (50)
        Entry = Key ('inventory') + >BlockList<
            length = 1
            Block
                Entry = Key ('id') + Value ("dagger")
                ... <several traditional entries like this>
                Entry = Key ('actions') + empty Block
    Entry = Key ('levels') + >BlockList<
        length = 2
        >Block<
            Entry = Key ('layout') + Layout
                <multiple lines that describe the layout>
            Entry = Key ('items') + empty BlockList
            Entry = Key ('entities') + empty BlockList
        >Block<
            Entry = Key ('layout') + Layout
                <multiple lines that describe the layout>
            Entry = Key ('items') + >BlockList<
                length = 1
                >Block<
                    Entry = Key ('id') + Value ("key")
                    ... <several traditional entries like this>
                    Entry = Key ('actions') + >Block<
                        Entry = >ConditionList< + Action ('retrieveItem(key)')
                            length = 1
                            Condition ('not(inventoryFull())')) 
                        Entry = empty ConditionList + Action ('leave()')
            Entry = Key ('entities') + >BlockList<
                length = 1
                >Block<
                    Entry = Key ('id') + Value ("door")
                    ... <several traditional entries like this>
                    Entry = Key ('actions') + >Block<
                        Entry = >ConditionList< + Action ('useItem(key)')
                            length = 1
                            Condition ('inventoryContains(key)')
                        Entry = empty ConditionList + Action ('leave()')

\pagebreak

Development notes

Assets & dependencies

The following assets were used (and modified if specified):

  • Kyrise's Free 16x16 RPG Icon Pack[1]

    Every needed asset was taken and put into its own .png, instead of in the overview.

  • 2D Pixel Dungeon Asset Pack by Pixel_Poem[2]

    Every needed asset was taken and put into its own .png, instead of in the overview.

RPG-Engine makes use of the following libraries:

Future development ideas

The following ideas could (or should) be implemented in the future of this project.

  • Entity system: With en ES, you can implement moving entities and repeated input. It also resembles the typical game loop more closely which can make it easier to implement other ideas in the future.

  • Game music: Ambient game music and sound effects can improve the gaming experience I think.

\pagebreak

References

[1] Kyrise's Free 16x16 RPG Icon Pack © 2018 by Kyrise is licensed under CC BY 4.0

[2] 2D Pixel Dungeon Asset Pack by Pixel_Poem is not licensed