Cauldron2D.GameMaker

Copy Markdown View Source

Reads the data file of a game made with GameMaker into Elixir structures a cauldron_2d game can use: sprites and their collision masks, texture pages, tilesets, objects and their events, rooms with their instances, tiles and layers, sounds, fonts, paths and scripts.

No game files are included. Point it at the data file of a game you own.

Installation

def deps do
  [
    {:cauldron_2d_gamemaker, "~> 0.2"}
  ]
end

Reading a game

{:ok, data} = Cauldron2D.GameMaker.Data.read("path/to/data.win")

data.general.format
data.rooms |> Enum.map(& &1.name)

{:ok, pictures} = Cauldron2D.GameMaker.Pictures.new(data)
frames = Cauldron2D.GameMaker.Pictures.sprite(pictures, hd(data.sprites))
mix gamemaker.info path/to/data.win
mix gamemaker.info path/to/data.win --list objects

The data file is data.win on Windows, game.ios in a macOS or iOS bundle's Resources, game.unx on Linux and game.droid on Android; all have the same layout.

modulewhat it reads
Datathe whole file: every resource below, in the game's own order, so a resource's index is its place in its list
Generalthe game's name, window, room order, frame rate and which GameMaker built it (:gms1, :gms2, :gms2_3)
Optionsdisplay settings and the game's constants
Spriteframes, origin, collision box and per-pixel masks as Cauldron2D.Masks (mask/2)
Region, Texturewhere a picture sits on a texture page, and the page itself
Picturesevery page decoded once, and any region, sprite, background or tile cut from them as a FrenchCurve.Raster
BackgroundGameMaker Studio 1 backgrounds and GameMaker Studio 2 tilesets (tile_source/2)
Object, Eventobjects with parent, depth, physics and events; event type names and the names of compiled event code (handler_name/3)
Roomsize, views, instances, and either backdrops and tiles (Studio 1) or layers (Studio 2): Room.Instance, Room.Tile, Room.View, Room.Backdrop, Room.Layer
Soundsounds, and the stored WAVE and Ogg bytes they index, from the data file or from an audio group file beside it (Data.audio_group/1)
Font, Path, Scriptglyphs and kerning, path points, script names

Running a game

The game's code is a module implementing Cauldron2D.GameMaker.Code: for each compiled name (gml_Object_Ball_Step_0, gml_Room_rTitle_Create, …) it returns a function of the world, the instance running it and the other instance of a collision.

world = Cauldron2D.GameMaker.World.new(data, MyGame.Code)
world = Cauldron2D.GameMaker.Step.run(world, %{held: held, pressed: pressed, released: released})
{world, items} = Cauldron2D.GameMaker.Draw.run(world)

table = Cauldron2D.GameMaker.Pictures.table(pictures, data)
raster = Cauldron2D.DrawList.render(items, {320, 200}, &Map.get(table, &1),
  view: {0, 0}, background: Cauldron2D.GameMaker.Draw.background(world))
modulewhat it does
Worldthe running game: instances in creation order, create and destroy, events with inheritance (perform/5, inherited/6), globals, room changes, the outbox
Stepone step in GameMaker's order: begin step, alarms, keyboard and mouse, step, motion, collisions, end step, animation, room change
Roomsleaving and entering rooms: placed instances, creation code, game start, room start and end
Collideinstance masks, place/4, meeting?/4, free?/3 and collision events
Drawthe frame as a Cauldron2D.DrawList: room backgrounds, tiles and layers, instances, draw and draw GUI events
InstanceGameMaker's built-in instance variables, motion kept in both forms

Limits

Files from GameMaker: Studio 1 and GameMaker Studio 2 up to 2.3 are read. Not read:

  • game code. A game built with the YoYo Compiler keeps its code in its executable as native functions named gml_Object_<object>_<Event>_<subtype> and gml_Script_<name>; its data file has no code to read. A game built for the GameMaker virtual machine carries bytecode in CODE, VARI and FUNC, which Data.bytecode?/1 detects; running it is not supported
  • QOI texture pages, written by GameMaker 2022.1 and later; Texture.decode/1 returns {:error, {:unsupported_encoding, :qoi}}
  • physics (Box2D) objects and rooms, paths followed by instances, timelines, and the asynchronous events
  • the older OPTN layout, the effect, path and sequence layers of rooms, sequences, timelines, shaders and extensions
  • the layout changes of GameMaker 2022 and later (room layer effects, sprite masks sized to the collision box, sound lengths)

License

MIT