int luab_Parallax_new(lua_State *L) {
    Parallax_userdata *ud = NULL;

    int c = lua_gettop(L);

    ud = lua_newuserdata(L, sizeof(Parallax_userdata));
    check(ud != NULL, "Could not make Parralax userdata");

    luaL_getmetatable(L, luab_Parallax_metatable);
    lua_setmetatable(L, -2);

    Parallax *parallax = Parallax_create();

    int i = 0;
    for (i = 0; i < c; i++) {
        ParallaxLayer *layer = luaL_toparallaxlayer(L, 1);
        Parallax_add_layer(parallax, layer);
        lua_remove(L, 1);
    }

    luaL_register_ud(L, -1, (void **)&ud->p, parallax);
    return 1;
error:
    return 0;
}
int luab_Music_new(lua_State *L) {
    Music_userdata *music_ud = NULL;
    Engine *engine = luaL_get_engine(L);

    int c = lua_gettop(L);
    const char *files[c];

    music_ud = lua_newuserdata(L, sizeof(Music_userdata));
    check(music_ud != NULL, "Could not make music userdata");

    luaL_getmetatable(L, luab_Music_metatable);
    lua_setmetatable(L, -2);

    int i = 0;
    for (i = 0; i < c; i++) {
        files[i] = lua_tostring(L, 1);
        lua_remove(L, 1);
    }

    Music *music = Audio_gen_music(engine->audio, c, files);

    luaL_register_ud(L, -1, (void **)&music_ud->p, music);
    return 1;
error:
    return 0;
}
int luab_NetMatch_new(lua_State *L) {
    NetMatch_userdata *ud = NULL;
    Engine *engine = luaL_get_engine(L);

    ud = lua_newuserdata(L, sizeof(NetMatch_userdata));
    check(ud != NULL, "Could not make NetMatch userdata");
    ud->p = NULL;

    luaL_getmetatable(L, luab_NetMatch_metatable);
    lua_setmetatable(L, -2);

    NetMatch *match = NetMatch_create(engine);
    luaL_register_ud(L, -1, (void **)&ud->p, match);
    return 1;
error:
    return 0;
}
int luab_Sensor_new(lua_State *L) {
    Sensor_userdata *ud = NULL;

    ud = lua_newuserdata(L, sizeof(Sensor_userdata));
    check(ud != NULL, "Could not make Sensor userdata");

    luaL_getmetatable(L, luab_Sensor_metatable);
    lua_setmetatable(L, -2);

    float w = lua_tonumber(L, 1);
    float h = lua_tonumber(L, 2);
    VPoint offset = luaL_tovpoint(L, 3);
    Sensor *sensor = Sensor_create(w, h, offset);
    check(sensor != NULL, "Could not make sensor");
    luaL_register_ud(L, -1, (void **)&ud->p, sensor);

    return 1;
error:
    return 0;
}
int luab_ParallaxLayer_new(lua_State *L) {
    ParallaxLayer_userdata *ud = NULL;
    Engine *engine = luaL_get_engine(L);

    ud = lua_newuserdata(L, sizeof(ParallaxLayer_userdata));
    check(ud != NULL, "Could not make ParralaxLayer userdata");

    luaL_getmetatable(L, luab_ParallaxLayer_metatable);
    lua_setmetatable(L, -2);

    const char *texname = lua_tostring(L, -2);
    GfxTexture *tex = Graphics_texture_from_image(engine->graphics,
            (char *)texname);
    check(tex != NULL, "Couldn't load image %s", texname);

    ParallaxLayer *layer = ParallaxLayer_create(tex);

    luaL_register_ud(L, -1, (void **)&ud->p, layer);
    return 1;
error:
    return 0;
}