Skip to content

GameObjectProgrammingGuide

DDR0 edited this page Dec 9, 2011 · 5 revisions

All dynamic components of a Frogatto level are controlled by objects. Objects are defined under `data/objects`. Each type of object has a FrogattoMarkupLanguage (FFL) file defining their behavior. This file may have one or more prototypes, which sets some default behaviour. For example, the ant has a prototype 'hittable', which makes the object respond to having something being thrown at it by default. Prototypes are defined in `data/object_prototypes`.

An object's definition contains several important pieces of data:

  • Basic object attributes: Its ID, number of hitpoints, physical behavior such as friction and traction, whether it's solid, etc.
  • Event handlers: Attributes beginning with `on_` are event handlers. Objects receive events, and an event handler defines how the object should respond to such an event. If you see `%PROTO%` in an event, have a look at that object's prototype file for additional code. If you see `swallow_event()`, then the object's prototype's code for that event will not be run.
  • Object animations: Contained inside `[animation]` tags, these define all the animations an object can enter.

Object Events

ObjectEvents are received by an object for a large variety of events. An event handler specifies what to do when an event occurs. As a simple example, to make an object bounce whenever it lands on the ground -- when the "collide_feet" event is captured -- we could mirror the y component of its velocity like this:

on_collide_feet="set(velocity_y, -velocity_y/2)"

An object event handler consists of a formula written in FrogattoFormulaLanguage (FFL). FFL is a _pure functional language_. That is to say, a formula does not directly modify any aspects of the game state. Rather, a formula executes, and returns results. These results are typically _commands_ that the game engine then executes on the object that triggered the event.

In the above example, the formula executes and returns a 'set' command which will set the velocity_y of the object.

The formula executed for an event handler has access to all of the ObjectProperties of the object the event is triggered on, and it may use them to calculate its result.

The formula has access to the ObjectFunctions API which contains many functions which can be used to create different kinds of commands that will be executed by the engine.

Structures

There are several logic structures that occur in FFL. 1 `if(*boolean expression*, *FFL to do if TRUE*, *FFL to do if FALSE*)` The *boolean expression* uses comparisons like `'<'`, `'!='`, and so on. Expressions may be chained together using boolean logic words, like `'and'` or `'or'`. Example: `x<y and y!=10`. Let's say `x = 5`. `if(x<5, debug('1'), debug('2'))` would print `'2'` to screen. Now, if x was 2, that expression would print `'1'` to screen. 1 `*FFL to do with variable* where *variable* = *FFL*` Executes the first FFL statement using *variable* as the last bit which *variable* equals. For example, `debug(x) where x = 10` would print `'10'` to screen. You can have several `where`s after a statement, like `debug(x,y) where x = 10 where y = 5` would print `'105'` to screen. 1 `map(*list*, *variable*, *FFL to do*)` The *FFL to do* is executed once for each item in the *list*, with that item being called *variable* in the *FFL to do*.

Notes: FFL to do can always be a list of FFL statements. `[debug('1'), debug('2')]` just causes both expressions to be run. Also, FFL is mostly whitespace insensitive. You can put hard returns, tabs, spaces, whatever between things. For example, the pound signs in the following statement can be replaced with whitespace without any effect. `#[#debug#(#'1'#)#,#debug#(#'2'#)#]#``

Clone this wiki locally