CPPFLAGS ?=
 CPPFLAGS += $(PKGFLAGS)
 CXXFLAGS ?=
-CXXFLAGS += -Wall
+CXXFLAGS += -Wall -Wextra -Werror
 #CXXFLAGS += -march=native
 LDXXFLAGS ?=
 LDXXFLAGS += $(PKGLIBS)
 
        Spawn(player.GetEntity(), spawn_block.GetChunk().Position(), spawn_block.GetBlockCoords());
 }
 
-void Spawner::Spawn(Entity &reference, const glm::ivec3 &chunk, const glm::vec3 &pos) {
+void Spawner::Spawn(Entity &, const glm::ivec3 &chunk, const glm::vec3 &pos) {
        Entity &e = world.AddEntity();
        e.Position(chunk, pos);
        e.Bounds({ { -0.5f, -0.5f, -0.5f }, { 0.5f, 0.5f, 0.5f } });
 
 
 // chase
 
-void ChaseState::Enter(AIController &ctrl, Entity &e) const {
+void ChaseState::Enter(AIController &, Entity &e) const {
        e.GetSteering()
                .SetAcceleration(5.0f)
                .SetSpeed(4.0f)
        ;
 }
 
-void ChaseState::Update(AIController &ctrl, Entity &e, float dt) const {
+void ChaseState::Update(AIController &ctrl, Entity &e, float) const {
        Steering &steering = e.GetSteering();
        // check if target still alive and in sight
        if (
        }
 }
 
-void ChaseState::Exit(AIController &ctrl, Entity &e) const {
+void ChaseState::Exit(AIController &, Entity &e) const {
        e.GetSteering().Disable(Steering::HALT | Steering::PURSUE_TARGET);
 }
 
        ctrl.CueDecision(6.0f, 3.0f);
 }
 
-void FleeState::Update(AIController &ctrl, Entity &e, float dt) const {
+void FleeState::Update(AIController &ctrl, Entity &e, float) const {
        if (!ctrl.DecisionDue()) return;
        ctrl.SetState(idle, e);
 }
 
-void FleeState::Exit(AIController &ctrl, Entity &e) const {
+void FleeState::Exit(AIController &, Entity &e) const {
        e.GetSteering().Disable(Steering::EVADE_TARGET);
 }
 
        ctrl.CueDecision(10.0f, 5.0f);
 }
 
-void IdleState::Update(AIController &ctrl, Entity &e, float dt) const {
+void IdleState::Update(AIController &ctrl, Entity &e, float) const {
        if (ctrl.MayThink()) {
                const Player *player = ctrl.ClosestVisiblePlayer(e);
                if (player) {
        ctrl.CueDecision(10.0f, 5.0f);
 }
 
-void IdleState::Exit(AIController &ctrl, Entity &e) const {
+void IdleState::Exit(AIController &, Entity &e) const {
        e.GetSteering().Disable(Steering::HALT | Steering::WANDER);
 }
 
        ctrl.CueDecision(10.0f, 5.0f);
 }
 
-void RoamState::Update(AIController &ctrl, Entity &e, float dt) const {
+void RoamState::Update(AIController &ctrl, Entity &e, float) const {
        if (ctrl.MayThink()) {
                const Player *player = ctrl.ClosestVisiblePlayer(e);
                if (player) {
        ctrl.CueDecision(10.0f, 5.0f);
 }
 
-void RoamState::Exit(AIController &ctrl, Entity &e) const {
+void RoamState::Exit(AIController &, Entity &e) const {
        e.GetSteering().Disable(Steering::WANDER);
 }
 
 
 }
 
 
-void MasterState::Handle(const SDL_Event &event) {
+void MasterState::Handle(const SDL_Event &) {
 
 }
 
        env.state.Push(state.get());
 }
 
-void MasterState::On(const Packet::Part &pack) {
+void MasterState::On(const Packet::Part &) {
        Quit();
        if (state) {
                // kicked
 
 
 }
 
+// relying on {} zero intitialization for UDPpacket, because
+// the type and number of fields is not well defined
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
 Client::Client(const Config::Network &conf)
 : conn(client_resolve(conf.host.c_str(), conf.port))
 , client_sock(client_bind(0))
 , client_pack{ -1, nullptr, 0 } {
+#pragma GCC diagnostic pop
        client_pack.data = new Uint8[sizeof(Packet)];
        client_pack.maxlen = sizeof(Packet);
        // establish connection
 uint16_t Client::SendPlayerUpdate(
        const EntityState &prediction,
        const glm::vec3 &movement,
-       float pitch,
-       float yaw,
+       float,
+       float,
        uint8_t actions,
        uint8_t slot
 ) {
        return old_actions != actions || !iszero(old_movement - GetMovement());
 }
 
-void NetworkedInput::Update(Entity &, float dt) {
+void NetworkedInput::Update(Entity &, float) {
        Invalidate();
        UpdatePlayer();
 }
 
 }
 #endif
 
-ostream &operator <<(ostream &out, const SDL_QuitEvent &evt) {
+ostream &operator <<(ostream &out, const SDL_QuitEvent &) {
        out << "quit";
        return out;
 }
 
 }
 
 
-void ServerState::Render(Viewport &viewport) {
+void ServerState::Render(Viewport &) {
 
 }
 
 
 }
 
 
+// relying on {} zero intitialization for UDPpacket, because
+// the type and number of fields is not well defined
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
 Server::Server(
        const Config::Network &conf,
        World &world,
 , save(save)
 , player_model(nullptr)
 , cli(world) {
+#pragma GCC diagnostic pop
        if (!serv_set) {
                throw NetError("SDLNet_AllocSocketSet");
        }
 
 }
 
 
-void TeleportCommand::Execute(CLI &cli, CLIContext &ctx, TokenStreamReader &args) {
+void TeleportCommand::Execute(CLI &, CLIContext &ctx, TokenStreamReader &args) {
        glm::vec3 pos(args.GetFloat(), args.GetFloat(), args.GetFloat());
        EntityState state = ctx.GetPlayer().GetEntity().GetState();
        state.pos = ExactLocation(pos).Sanitize();
 
 
 }
 
-void WorldResources::Load(const AssetLoader &loader, const std::string &set) {
-       loader.LoadShapes("default", shapes);
-       loader.LoadBlockTypes("default", block_types, snd_index, tex_index, shapes);
-       loader.LoadModels("default", models, tex_index, shapes);
+void WorldResources::Load(const AssetLoader &loader, const std::string &set_name) {
+       loader.LoadShapes(set_name, shapes);
+       loader.LoadBlockTypes(set_name, block_types, snd_index, tex_index, shapes);
+       loader.LoadModels(set_name, models, tex_index, shapes);
 }
 
 }
 
        }
 }
 
-void MessageState::Update(int dt) {
+void MessageState::Update(int) {
 
 }
 
 
 
 }
 
-void PreloadState::Update(int dt) {
+void PreloadState::Update(int) {
        loader.LoadN(per_update);
        if (loader.ToLoad() <= 0) {
                env.state.Pop();
        // ignore everything
 }
 
-void UnloadState::Update(int dt) {
+void UnloadState::Update(int) {
        for (std::size_t i = 0; i < per_update && cur != end; ++i, ++cur, ++done) {
                if (cur->ShouldUpdateSave()) {
                        save.Write(*cur);
 
        Insert(e.text);
 }
 
-void TextInput::Handle(const SDL_TextEditingEvent &e) {
+void TextInput::Handle(const SDL_TextEditingEvent &) {
+
 }
 
 void TextInput::Refresh() {
 
 
 }
 
-void ChunkLoader::Update(int dt) {
+void ChunkLoader::Update(int) {
        // check if there's chunks waiting to be loaded
        // load until one of load or generation limits was hit
        constexpr int max_load = 10;
 
 
 Ray Entity::Aim(const ExactLocation::Coarse &chunk_offset) const noexcept {
        glm::mat4 transform = ViewTransform(chunk_offset);
-       Ray ray{ glm::vec3(transform[3]), -glm::vec3(transform[2]) };
+       Ray ray{ glm::vec3(transform[3]), -glm::vec3(transform[2]), { } };
        ray.Update();
        return ray;
 }
        }
 }
 
-void Entity::OrientHead(float dt) noexcept {
+void Entity::OrientHead(float) noexcept {
        // maximum yaw of head (60°)
        constexpr float max_head_yaw = PI / 3.0f;
        // use local Y as up
        return true;
 }
 
-void Player::Update(int dt) {
+void Player::Update(int) {
        chunks.Rebase(entity.ChunkCoords());
 }
 
        return TargetVelocity(state, glm::normalize(entity.Heading() * wander_dist + wander_pos) * speed);
 }
 
-glm::vec3 Steering::ObstacleAvoidance(const EntityState &state) const noexcept {
+glm::vec3 Steering::ObstacleAvoidance(const EntityState &) const noexcept {
        return obstacle_dir;
 }
 
 
 
 
 void IntersectionTest::testSimpleRayBoxIntersection() {
-       Ray ray{ { 0, 0, 0 }, { 1, 0, 0 } }; // at origin, pointing right
+       Ray ray{ { 0, 0, 0 }, { 1, 0, 0 }, { } }; // at origin, pointing right
        ray.Update();
        AABB box{ { -1, -1, -1 }, { 1, 1, 1 } }; // 2x2x2 cube centered around origin
 
 }
 
 void IntersectionTest::testRayBoxIntersection() {
-       Ray ray{ { 0, 0, 0 }, { 1, 0, 0 } }; // at origin, pointing right
+       Ray ray{ { 0, 0, 0 }, { 1, 0, 0 }, { } }; // at origin, pointing right
        AABB box{ { -1, -1, -1 }, { 1, 1, 1 } }; // 2x2x2 cube centered around origin
        glm::mat4 M(1); // no transformation