Video Game Bricks

I don’t believe in game engines. I tend to consider software development as the process of using existing bricks together with glue code to obtain the expect result, whereas engines provide the final result with the holes to be filled in. This is not to say that game engines are useless—countless situations can benefit from them. However, my approach to game development has always been to rely on frameworks and collections of helper and utility classes, perhaps due to my beginnings as a DirectDraw programmer.

Objective Caml games do exist, even though they often lack the backing of a full video game studio. Whether used as a prototyping tool or to develop the final product, I think the functional approach can benefit video game development. To that end, I regularly develop small bricks that can be useful for game development. All of the source code presented here is my own work, placed in the public domain.

Vectors and Transforms

Bidimensional vectors with supporting elementary mathematical operators:

type vector = { x : float; y : float } 

val right : vector
val up : vector
val zero : vector 

val equal : vector -> vector -> bool 

val ( ++ ) : vector -> vector -> vector
val ( -- ) : vector -> vector -> vector
val ( *+ ) : float -> vector -> vector 

val sqlen : vector -> float
val len : vector -> float 

exception ZeroVector
val normalize : vector -> vector 

val dot : vector -> vector -> float

The operators behave as expected. Equality and normalization work with a fixed epsilon of 1e-6. The total memory usage for a vector is 20 bytes (16 for the coordinates, 4 for internal usage), and they are manipulated by reference. Intermediary operations on vectors tend to be inlined, and intermediary values are garbage-collected when present.

Bidimensional transforms and corresponding operations:

type transform 

val identity   : transform
val rotate     : transform -> float -> transform
val scale      : transform -> float -> transform
val translate  : transform -> Vector.vector -> transform 

type transform_description =
    {
      angle    : float;
      scale    : float;
      position : Vector.vector
    } 

val make       : transform_description -> transform
val describe   : transform -> transform_description 

val apply      : transform -> Vector.vector -> Vector.vector
val compose    : transform -> transform -> transform

This type represents similarities. The total memory usage is 36 bytes (32 for the coordinates, 4 for internal usage), and they are manipulated by reference.

Downloads: vector.ml vector.mli transform.ml transform.mli

Indexing

When using functional programming, the aliasing problem makes it impossible to have several data structures directly reference a certain value without having to update all data structures when that value changes. A solution to that problem is to store indirect references instead: the value is stored in a single data structure and bound to a key. The other data structures do not reference the value, but rather “whatever the key is bound to”. Meaning that changing the single data structure holding the value also implicitely updates the value for all other data structures.

An indexing data structure provides exactly that: a way of binding a value to a key and retrieving it with that key. If no backtracks happen, then the following implementation performs all relevant operations in amortized constant time.

type         'a t
type         handle
exception    UnboundHandle 

val empty  : int -> 'a t 

val add    : 'a -> 'a t -> 'a t * handle
val remove : handle -> 'a t -> 'a t
val get    : handle -> 'a t -> 'a 

val map    : ('a -> 'b) -> 'a t -> 'b t
val mapi   : (handle -> 'a -> 'b) -> 'a t -> 'b t
val iter   : ('a -> unit) -> 'a t -> unit
val iteri  : (handle -> 'a -> unit) -> 'a t -> unit
val fold   : (handle -> 'a -> 'b -> 'b) -> 'b -> 'a t -> 'b

Note that “UnboundHandle” is not necessarily raised. If it is, then you know what happened. However, attempting to access a removed handle is, in the general case, undefined, and may return another value.

You can also look for persistent arrays for generic data storage.

Downloads: assoc.ml assoc.mli

0 Responses to “Video Game Bricks”


  1. No Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>



706 feed subscribers
(readers who polled a feed this week)