Difference between revisions of "Greyout"

From Pandora Wiki
Jump to: navigation, search
m
m
Line 13: Line 13:
 
====Folder structure====
 
====Folder structure====
 
[[File:Greyout folder structure.png|frame|Folder structure]]
 
[[File:Greyout folder structure.png|frame|Folder structure]]
{|class="wikitable" border="1" cellpadding="1" cellspacing="0" style="font-size: 90%; border:1px solid gray; border-collapse: collapse; text-align: center; width: 90%;"
+
{|class="wikitable" border="1" cellpadding="1" cellspacing="0" style="font-size: 90%; border:1px solid gray; border-collapse: collapse; text-align: center; width: 75%;"
 
|- style="background: #ececec"
 
|- style="background: #ececec"
 
!Folder
 
!Folder

Revision as of 22:37, 13 April 2011

Greyout is a mind-bending puzzle-platformer created by foxblock for the 2011 unofficial OpenPandora platformer competition.

About the game

Premise

none (to be continued)

User content

A large part of the development of Greyout has been devoted to ease the process for custom content to be created and loaded into the game.

Introduction

Folder structure

Folder structure
Folder Description
chapters Chapters (single folders) go here (for example the default chapter is "chapters/default")
data Contains some minor, non important game data
fonts Fonts are located here
images All images are here, unit sprites for example are in "images/player" or "images/units", the default levels are in "images/levels", "images/general" has logos and stuff and "images/menu" holds the menu backgrounds
levels Single level files go here (directly on a PC or the "appdata/greyout/levels" folder on a Pandora)
music Default music files are located here, you may use them in your levels
preview Preview Images for the PND (not important)
sounds Menu and player sounds are in here

Types of content

Through the magic appdata system of libpnd you can overwrite any data of the game and by that skin the player to your liking or change the music. Then there are multiple types of user created content you can load into the game, but the most used will be "Single Levels" and "Chapters".

Single Levels

Single levels are, as the name suggests, single .txt files representing a level, they can access any data of the original game (images, music, sounds) as well as supply new data which has to go in the main folders, though. So in general if you want to supply your own level images or music you should create a chapter as copying your custom data in the main folder posts the risk of accidentally overwriting stuff. On the other hand, if you want to make a spin-off of one of the original levels or solely use original data a single level is perfectly fine.

Single levels go into the "levels" folder and will be auto-detected and displayed in the "Single levels" menu item on the level selection screen.

Chapters

A chapter is a folder created in the "chapters" directory with an "info.txt" file inside of it containing additional options (more an that in the last section).

Chapters work the same way as single levels in many ways, but they have one big advantage as creating a chapter basically lets you mirror the data structure of the game into a child folder. What is meant by that is that you can put a custom image you want to load in your chapter folder and can refer to it by a relative path from your "info.txt" file. If the game does not manage to find the custom data it will automatically try to pick up the file from the default data (in the PND). That way you can make use of default and custom data alongside without overwriting any actual data. If you want to overwrite existing references you just have to put a custom file in the same relative location from your "info.txt" file (i.e. supply a "images/player/black_big.png" in your chapter to overwrite the default, black player image in your chapter). Such "overwrites" however will not affect other chapters including the default one.

Chapters go into the "chapters" folder and will be displayed as an additional item on the main level selection screen (alongside the default chapter and "Single levels" item). Levels used in a chapter will not be auto-detected and have to be specified in the "info.txt" file, more on that in the last section.

Loading user content

When downloading user created content it will most likely come compressed as a .zip or .tar.gz. To get that data into the game you will need to extract it (the Pandora is able to do that, too). Ideally each download should come with a short description of what you have to do, but in case it does not here are the general instructions.

All data has to be placed on your SD card in the "appdata/greyout" folder (or simply the main game folder if you are on a PC), if that folder is not present, create it or simply run the game once (your savegame will also be placed there).

Single levels should be a single .txt file (and might not always be zipped) and go in the "levels" folder, which would be "appdata/greyout/levels" (or simply "levels" on a PC) then. If the single level, despite all warnings, packs additional content, such as images and music, you will most likely have to extract it to the main folder "appdata/greyout".

Chapters should be a single folder and simply have to be placed in the "chapters" folder ("appdata/greyout/chapters" on the Pandora).

Creating your own

Level structure

Level files are plain-text files and must have the file extension .txt, also don't use Unicode encoding.

They are structured very similar to ini-files. They consist of fields starting with the field name in square brackets (i.e. "[Level]") and ending on the next field (so no field delimiter like "[/Level]" is required or even valid).

Inside the field definition you can place parameter definitions which have a key=value syntax (i.e. "Class=Generic"). You must place one key-value-pair per line. Commas (",") are used for separating multiple values in a key-value-pair (i.e. for x and y position). Here the "Class" property has to be specified first, afterwards the order does not matter.

You can make use of comments to explain the level code which start with a diamond key ("#") and make the load code skip this one line (there is no code for commenting out multiple lines at once like "/* */").

Another important thing to note is that the last line of the file must not be empty (that is a "bug" in the loading code I am trying to fix), so end the file after the last key-value-pair and don't add another blank line or the last field will not be loaded properly!

Level files are loaded case in-sensitive (keys AND values), so writing "[Level]" or "[lEvEl]" will make no difference (substituting Es with 3s however will...).

The first filed in a level file has to be "Level" afterwards you are not limited to any order of fields, but be aware that in-case you are referring from one field to another (i.e. linking a key to a door) the linked field has to come first in the file (i.e. specify the door first an the key afterwards).

Example file

This is a commented and simplified version of level 3 of the game ("Elevator Action"). The only change is that extra blocks have been removed from the first three elevators.

# This is a comment line it will be ignored on load
# Level field definition has to come first
[Level]
# Defines the type of level (changes how units behave), you will mostly use "Generic"
# The class property has always to be the first property!
Class=Generic
# Specifies the background (and collision) image, in chapters this can be a relative path to the info.txt file
Image=images/levels/02.png
# List of level flags, separated by commas
# RepeatY means the level will wrap in vertical direction (what falls down comes back up top)
Flags=RepeatY,RepeatX
# Background music (will loop)
Music=music/alone.ogg
# The name will be displayed when the level loads, this is entirely optional
Name=Elevator Action
# End of level field definition as a new field is encountered
# Next come all the units in the level, you don't have to obey any order here, but
# I try to keep it Players,other Units, Items, Exits
[Player]
# Defines the type of player - the "Class" property is _always_ required!
Class=black
# Position is in pixels and relative to the top-left corner of the level (which is 0,0)
# The position specifies the top-left corner of the unit (NOT the centre)
Position=48,160
# Sets whether the player should be controllable initially (at least one player should)
Control=true
# There are more properties we could set here, but the default values are fine so we don't need to
[Unit]
# This is the first elevator going up slowly
Class=SolidBox
Position=64,0
# Velocity in pixels, positive values for x mean movement to the right, for y they mean movement to the bottom
Velocity=0,-2
# As this is a simple rectangle setting colour actually paints the unit
# This currently does not work on sprite-based units, 
# which will behave based on the colour property but always look like the sprite
Colour=black
# Size in pixels
Size=64,64
[Unit]
# This is the second elevator going down slowly
Class=SolidBox
Position=160,32
Velocity=0,2
Colour=black
Size=64,64
[Unit]
# This is (as you may have guessed) the third elevator
Class=SolidBox
Position=224,0
Velocity=0,-2
Colour=black
Size=64,64
[Unit]
# This is the last elevator for the single box
Class=SolidBox
Position=608,0
Velocity=0,-1
Colour=black
[Unit]
# This is said single, pushable box
Class=PushableBox
Position=672,64
Colour=black
Collision=black,red
# The missionObjective flag will restart the level if this unit is destroyed
# This avoids unsolvable puzzles
Flags=missionObjective
health=0
[Unit]
# This is the red box in the second elevator
# I could have also painted it on the level file, but as every unit is always
# drawn in front of the level the elevator would have covered it then
# Also note: any unit specified later in the level file will be drawn on top of others before
Class=SolidBox
Position=160,96
# Being a simple rectangle this colour property actually affects the in-game colour of the unit
# not just the collision behaviour, also no extra effort is required to make it deadly as
# red currently automatically means death
Colour=red
Size=64,64
[Unit]
Class=SolidBox
Position=608,224
Colour=red
[Unit]
# This is the exit of the level (duh)
Class=Exit
Position=534,24
# Specifies that the black player can exit the level through this one
Collision=black
Error handling
Screenshot of the level selection screen showing an error
This level is faulty

Okay, so now you wrote your level put it in the correct folder and still all you get is an error image like the one on the right (or the level does not behave as intended).

Well, that means you made an error somewhere but how to fix it when all the game tells you is "ERROR". Actually that is not true, the game prints many, detailed status and error messages through the C++ magic of "cout". These messages will be stored depending on your operating system.

On Windows: A "stdout.txt" file will be created next to the .exe file

On Linux: If you are running the game from a console it will be put there, if not you are out of luck, but you can redirect the output to a file using the supplied "run.sh" shell-script which will place all output in "tmp/greyout.log" (lesson here: for development purposes always run the shell script).

On the Pandora: A "pndrun_greyout.out" file will be created in the "/tmp" folder on your SD card.

This file will contain human read-able versions of the errors encountered, just search for a line "Trying to load level file "YOURLEVELNAME.txt"" and check the following lines.

If you are encountering many "Unknown unit class"-errors, see whether there is a new version of the game available in which those units were added.

Example
[...]
Trying to load level file "levels/video.txt"
Loading new image to cache "../media/video_level.png"
Warning: Unprocessed parameter "ping" on level "generic"
Error: Unknown player class "asdf" on line 10
Warning: No controlable unit found! Push the buttons...(nothing happens)
Finished loading level file with minor errors!
[...]

Reference

Data type reference

Data Type Example Description
Boolean true Recognized in string form are "1" and "true" for true, anything else will be interpreted as false
Colour Red Either a number-based colour code (red + 255*green + 255*255*blue) or a string-based one (recognized values: [1])
Number 42.18 An integer or float value
Set(...) RepeatX,RepeatY A set of ident strings representing several objects of type ..., sets are not limited in length and allow only a single type
String foo bar A simple string as you may know it, no control characters are allowed
Struct(...) 42,18 A struct of values separated by commas, the types of the values might be represented instead of the ..., different types possible and fixed in length

Field reference

Fields are the filed ident written in brackets (i.e. [Level]), they are followed by Key=Value pairs specifying the parameters.

Field ident Description
Level Specifies the level object, this has to be the first field in the file and is limited to one
Player Creates a controllable unit, see unit class list for available types
Unit Creates an ordinary unit

List of level classes

Use the Class name as the value for the "Class" key in the "Level" field.

Class name Description Default parameter values
Generic The default level class you will most likely use for all purposes
Benchmark Creates a benchmark level which will not take any control and measure the fps for 10 seconds, then calculate and write some values to stdout and exit the game
Playground Has special controls to modify the level at run-time, you can draw black/white rectangles with the mouse and spawn black/white PushableBoxes with Y/X

Level parameter reference

Base properties

Apply to all level classes.

Key Data Type Mandatory Description Default value
Background Colour Sets the colour of the area outside and behind the level file (so only useful on transparent or small levels) Black
Boundaries Boolean Sets whether the camera may move outside the level and show the void around it (only useful on big levels) false
Class String yes Specifies the class of the level to create (check table above), has to be the first key
Dialogue String Path and filename of a text-file containing the dialogue lines for DialogueTriggers (will become deprecated in 1.0.1.4)
Flags Set(Boolean) RepeatX (activates horizontal wrapping), RepeatY (vertical wrapping), DisableSwap (disables the player's ability to switch units), KeepCentred (keeps the camera on the unit - use in levels bigger as the screen), ScaleX (scales the level to the size of the screen horizontally, currently very slow!), ScaleY (same vertically)
Image String yes Path and filename of the image your want to load as the background and for collision
Music String Path and filename of the music file to play in the background
Name String The name displayed after loading the level
Offset Struct(Number,Number) Sets the camera to a fixed offset (don't use in combination with KeepCentred flag) 0,0

List of unit and player classes

Use the Class name as the value for the "Class" key in the "Player" (Parent = ControlUnit) or "Unit" field.

Default values can be overwritten, child classes will also inherit the parent class' default values.

Class name Parent class Description Default parameter values
Black ControlUnit The default black player unit (basically just an alias for a generic player unit with some values set) Collision (black,red), ImageOverwrite (images/player/black_big.png), Colour (Black)
DialogueTrigger BaseUnit When hit by a player will load and display a line from the dialogue list
Exit BaseUnit Well... it makes a touching player exit the map, you have to make the exit available to certain players by adding the colour of the player to the "Collision" property Flags (NoMapCollision,NoGravity,NoCollisionDraw), Colour (3566735)
Generic BaseUnit A generic player unit, will load the black sprite set as default, but without the values set (=Control Unit) Flags (MissionObjective)
PushableBox BaseUnit A solid, pushable box which you can give a colour Colour (Black)
SolidBox PushableBox Same as PushableBox, except it is not pushable - use it for elevators or stationary hazards Flags (NoGravity,NoMapCollision,NoUnitCollision,Invincible)
White ControlUnit The default white player unit Collision (white,red), ImageOverwrite (images/player/white_big.png), Colour (White)

Unit parameter reference

Sorted by class.

Child classes usually inherit parent properties, except stated otherwise, and sometimes overwrite some.

Base properties
Key Data Type Mandatory Description Default value
Class String yes The class of the unit to create (check table above), has to be the first property in the list
Collision Set(Colour) Specifies the colours with which the unit should collide, if none are specified at least the colour of the unit is added to the list
Colour Colour The colour representing this unit (actually colours all non-sprite based units, too) White
Flags Set(Boolean) Invincible (Makes the unit immune to damage), MissionObjective (The level will be restarted if this unit is killed), NoCollisionDraw (Prevents this unit from being updated on the collision surface, deprecated), NoGravity (Gravity will not be applied to this unit), NoMapCollision (Will not check for collision with the map), NoUnitCollision (Will not check for collision with other units - currently only useful for ControlUnits)
Health Number (Integer) Number of ticks the unit can survive being squashed or touching a hazard (0-based so 0 will not immediately kill a unit) 0
ImageOverwrite String Filename and path of an image file to load instead of the default one, keep in mind that the custom one has to have the same number of horizontal and vertical tiles (not necessarily the same size in pixels) and the same layout, use the default one as a template
Position Record(Number,Number) Position of the top-left corner of the unit in the level in pixel-coordinates (x,y) 0,0
Velocity Record(Number,Number) Starting velocity of the unit in pixels per frame, use to make moving platforms and elevators 0,0
DialogueTrigger

Will not be rendered so setting a "Colour" only to make sure a unit can collide with this trigger (additionally don't forget to set the "Collision" property for the same reason), also setting ImageOverwrite will have no effect.

Key Data Type Mandatory Description Default value
Size Record(Number,Number) Size of the trigger in pixels 32,32
TextKey String yes Key of the line to load in the dialogue file
Time Number (Integer) Time the line will be shown on screen in milliseconds 1000
Generic (aka ControlUnit)
Key Data Type Mandatory Description Default value
Control Boolean Specifies whether the unit takes input (might be changed by the user during gameplay) true
PushableBox

Non-sprite-based unit, so setting "ImageOverwrite" will have no effect.

Key Data Type Mandatory Description Default value
Size Record(Number,Number) Size of the box in pixels 32,32

Chapter and info.txt parameter reference

The "info.txt" file contains information about the chapter and is mandatory for it to work properly. It is similar to the level file in structure, but only uses Key=Value pairs and no field as those re not needed.

Key Data Type Mandatory Description
Image String Filename and path to an icon used to display the chapter in the selection screen, path relative from the info.txt file, icon should be 175x105 pixels in size (else it will be scaled), if no image is set text reading the chapter name will be displayed
Level String yes Filename and path of a level file to add to the chapter, you can use this key multiple times to add more levels, this also defines the order the levels will appear and be played in, path relative to info.txt file location
Name String yes Name of the chapter, will be displayed if no image is loaded

Dialogue system

(soon...)