QUOTE: Enjoy small things, cherish moments.

feat: Added web support & small changes - freezo - A retro platform game

freezo

A retro platform game
git clone git@soophie.de:/srv/git/freezo
log | files | refs | readme

commit c0da7956d7ec3de9e29a3d87442c323d41c45195
parent a19857eb6d1b1249122d227d518a56b12383136f
Author: Sophie <info@soophie.de>
Date:   Sun, 15 Dec 2024 21:55:52 +0100

feat: Added web support & small changes

Diffstat:
M.gitignore | 2+-
MMakefile | 16++++++++++++----
Massets/entities.png | 0
Rsrc/const.h -> include/const.h | 0
Ainclude/effect.h | 26++++++++++++++++++++++++++
Ainclude/enemy.h | 31+++++++++++++++++++++++++++++++
Rsrc/entity.h -> include/entity.h | 0
Rsrc/game.h -> include/game.h | 0
Ainclude/gate.h | 19+++++++++++++++++++
Rsrc/level.h -> include/level.h | 0
Rsrc/menu.h -> include/menu.h | 0
Ainclude/player.h | 32++++++++++++++++++++++++++++++++
Rsrc/tile.h -> include/tile.h | 0
Ainclude/util.h | 42++++++++++++++++++++++++++++++++++++++++++
Rsrc/libs/raylib.h -> lib/raylib.h | 0
Rsrc/libs/raymath.h -> lib/raymath.h | 0
Msrc/effect.c | 18+++++++++---------
Dsrc/effect.h | 26--------------------------
Msrc/enemy.c | 28++++++++++++++--------------
Dsrc/enemy.h | 31-------------------------------
Msrc/entity.c | 6+++---
Msrc/game.c | 16++++++++--------
Msrc/gate.c | 12++++++------
Dsrc/gate.h | 19-------------------
Msrc/level.c | 10+++++-----
Msrc/main.c | 43+++++++++++++++++++++++++++++--------------
Msrc/menu.c | 15+++++++++------
Msrc/player.c | 32++++++++++++++++----------------
Dsrc/player.h | 32--------------------------------
Msrc/tile.c | 8++++----
Msrc/util.c | 18+++++++++---------
Dsrc/util.h | 42------------------------------------------
32 files changed, 275 insertions(+), 249 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -1,2 +1,2 @@ -.DS_Store freezo +build/ diff --git a/Makefile b/Makefile @@ -1,8 +1,16 @@ -build: - cc -o freezo -I/opt/homebrew/Cellar/raylib/5.0/include -L/opt/homebrew/Cellar/raylib/5.0/lib -lraylib -rdynamic -Wall -Wextra -Werror -pedantic src/*.c +CC=cc +CFLAGS=-Werror -Wall -Wextra -pedantic +LIBS=-I/opt/homebrew/Cellar/raylib/5.0/include -L/opt/homebrew/Cellar/raylib/5.0/lib -lraylib + +build: src/*.c + mkdir -p ./build + $(CC) -o ./build/freezo $(CFLAGS) $(LIBS) $^ run: build - ./freezo + ./build/freezo + +web: src/*.c + emcc -o ./build/freezo.html $^ -Os -Wall ../raylib/src/libraylib.a -I. -L. -Lpath-to-libraylib-a -s USE_GLFW=3 -DPLATFORM_WEB --preload-file ./assets clean: - rm freezo + rm -rf ./build diff --git a/assets/entities.png b/assets/entities.png Binary files differ. diff --git a/src/const.h b/include/const.h diff --git a/include/effect.h b/include/effect.h @@ -0,0 +1,26 @@ +#pragma once + +typedef struct Effect effect_t; + +#include "game.h" +#include "util.h" + +typedef enum { + EFFECT_FALL, + EFFECT_BREAK, + EFFECT_PARTICLE, +} effect_e; + +struct Effect { + effect_e type; + pos_t pos; + fz_timer_t *timer; + int count; +}; + +effect_t *effect_create(pos_t pos, effect_e type); +void effect_update(effect_t *effect, game_t *game); +void effect_draw(effect_t *effect, game_t *game); +void effect_free(effect_t *effect); + +void effect_play(pos_t pos, effect_e type, game_t *game); diff --git a/include/enemy.h b/include/enemy.h @@ -0,0 +1,31 @@ +#pragma once + +typedef struct Enemy enemy_t; + +#include "game.h" +#include "util.h" + +typedef enum { + ENEMY_TEST, +} enemy_e; + +struct Enemy { + pos_t pos; + enemy_e type; + bool on_ground; + float velocity; + float gravity; + int dir; + bool stunned; + bool frozen; + int frozen_timer; + float fall_height; + fz_timer_t *timer_walking; + fz_timer_t *timer_sneaking; +}; + +enemy_t *enemy_create(pos_t pos, enemy_e type); +void enemy_update(enemy_t *enemy, game_t *game); +void enemy_draw(enemy_t *enemy, game_t *game); +void enemy_kill(enemy_t *enemy, game_t *game); +void enemy_free(enemy_t *enemy); diff --git a/src/entity.h b/include/entity.h diff --git a/src/game.h b/include/game.h diff --git a/include/gate.h b/include/gate.h @@ -0,0 +1,19 @@ +#pragma once + +typedef struct Gate gate_t; + +#include "game.h" +#include "util.h" + +struct Gate { + pos_t pos; + int enemy_max; + fz_timer_t *timer_spawn; + bool frozen; + int frozen_timer; +}; + +gate_t *gate_create(pos_t pos, int enemy_max, int time); +void gate_update(gate_t *gate, game_t *game); +void gate_draw(gate_t *gate, game_t *game); +void gate_free(gate_t *gate); diff --git a/src/level.h b/include/level.h diff --git a/src/menu.h b/include/menu.h diff --git a/include/player.h b/include/player.h @@ -0,0 +1,32 @@ +#pragma once + +typedef struct Player player_t; + +#include "util.h" +#include "enemy.h" +#include "game.h" +#include "entity.h" + +struct Player { + pos_t pos; + int health; + bool on_ground; + float velocity; + float gravity; + int dir; + bool sneaking; + bool shooting; + int damage_timer; + float fall_height; + enemy_t *held_enemy; + bool moving; + fz_timer_t *timer_walking; + fz_timer_t *timer_sneaking; + entity_t *target_entity; + float shooting_distance; +}; + +player_t *player_create(pos_t pos); +void player_update(player_t *player, game_t *game); +void player_draw(player_t *player, game_t *game); +void player_free(player_t *player); diff --git a/src/tile.h b/include/tile.h diff --git a/include/util.h b/include/util.h @@ -0,0 +1,42 @@ +#pragma once + +#include <stdbool.h> + +#include "../lib/raylib.h" + +#define UNUSED(x) (void)(x) + +typedef Vector2 pos_t; +typedef Rectangle rect_t; +typedef struct Timer fz_timer_t; + +#include "game.h" + +struct Timer { + int frames; + int count; + int step; +}; + +fz_timer_t *fz_timer_create(int frames, int step); +bool fz_timer_check(fz_timer_t *timer); +void fz_timer_update(fz_timer_t *timer); +void fz_timer_reset(fz_timer_t *timer); +int fz_timer_get(fz_timer_t *timer); +void fz_timer_free(fz_timer_t *timer); + +pos_t pos_snap(pos_t vec); + +rect_t rect_from_pos(pos_t pos, int width, int height); +bool rect_collide(rect_t a, rect_t b); + +Texture texture_load(char *filename, int scale); +Rectangle texture_rect(int x, int y, int width, int height); + +typedef enum { + TEXT_ALIGNMENT_LEFT, + TEXT_ALIGNMENT_RIGHT, + TEXT_ALIGNMENT_CENTER, +} text_alignment_e; + +void text_draw(pos_t pos, char *text, text_alignment_e alignment, game_t *game); diff --git a/src/libs/raylib.h b/lib/raylib.h diff --git a/src/libs/raymath.h b/lib/raymath.h diff --git a/src/effect.c b/src/effect.c @@ -1,8 +1,8 @@ #include <stdlib.h> -#include "effect.h" -#include "util.h" -#include "const.h" +#include "../include/effect.h" +#include "../include/util.h" +#include "../include/const.h" effect_t *effect_create(pos_t pos, effect_e type) { effect_t *effect = malloc(sizeof(effect_t)); @@ -10,13 +10,13 @@ effect_t *effect_create(pos_t pos, effect_e type) { effect->pos = pos; switch (type) { case EFFECT_FALL: - effect->timer = timer_create(7, 3); + effect->timer = fz_timer_create(7, 3); break; case EFFECT_BREAK: - effect->timer = timer_create(10, 3); + effect->timer = fz_timer_create(10, 3); break; case EFFECT_PARTICLE: - effect->timer = timer_create(14, 4); + effect->timer = fz_timer_create(14, 4); break; } effect->count = 0; @@ -24,8 +24,8 @@ effect_t *effect_create(pos_t pos, effect_e type) { } void effect_update(effect_t *effect, game_t *game) { - timer_update(effect->timer); - if (timer_check(effect->timer)) { + fz_timer_update(effect->timer); + if (fz_timer_check(effect->timer)) { effect->count++; } // remove effect after one iteration @@ -58,7 +58,7 @@ void effect_draw(effect_t *effect, game_t *game) { x = 3; break; } - int frame = timer_get(effect->timer); + int frame = fz_timer_get(effect->timer); DrawTextureRec(game->assets.entities, texture_rect(frame, x, PLAYER_WIDTH, PLAYER_HEIGHT), pos_snap(effect->pos), WHITE); } diff --git a/src/effect.h b/src/effect.h @@ -1,26 +0,0 @@ -#pragma once - -typedef struct Effect effect_t; - -#include "game.h" -#include "util.h" - -typedef enum { - EFFECT_FALL, - EFFECT_BREAK, - EFFECT_PARTICLE, -} effect_e; - -struct Effect { - effect_e type; - pos_t pos; - timer_t *timer; - int count; -}; - -effect_t *effect_create(pos_t pos, effect_e type); -void effect_update(effect_t *effect, game_t *game); -void effect_draw(effect_t *effect, game_t *game); -void effect_free(effect_t *effect); - -void effect_play(pos_t pos, effect_e type, game_t *game); diff --git a/src/enemy.c b/src/enemy.c @@ -1,10 +1,10 @@ #include <stdlib.h> #include <math.h> -#include "enemy.h" -#include "const.h" -#include "entity.h" -#include "effect.h" +#include "../include/enemy.h" +#include "../include/const.h" +#include "../include/entity.h" +#include "../include/effect.h" enemy_t *enemy_create(pos_t pos, enemy_e type) { enemy_t *enemy = malloc(sizeof(enemy_t)); @@ -19,8 +19,8 @@ enemy_t *enemy_create(pos_t pos, enemy_e type) { .frozen = false, .frozen_timer = 0, .fall_height = 0.0, - .timer_walking = timer_create(9, 8), - .timer_sneaking = timer_create(9, 16), + .timer_walking = fz_timer_create(9, 8), + .timer_sneaking = fz_timer_create(9, 16), }; return enemy; } @@ -157,19 +157,19 @@ void enemy_update(enemy_t *enemy, game_t *game) { } // update timer if (enemy->on_ground && !enemy->frozen) { - timer_update(enemy->timer_walking); - timer_update(enemy->timer_sneaking); + fz_timer_update(enemy->timer_walking); + fz_timer_update(enemy->timer_sneaking); } else { - timer_reset(enemy->timer_walking); - timer_reset(enemy->timer_sneaking); + fz_timer_reset(enemy->timer_walking); + fz_timer_reset(enemy->timer_sneaking); } } void enemy_draw(enemy_t *enemy, game_t *game) { pos_t pos = pos_snap(enemy->pos); - int frame_walking = timer_get(enemy->timer_walking); - int frame_sneaking = timer_get(enemy->timer_sneaking); + int frame_walking = fz_timer_get(enemy->timer_walking); + int frame_sneaking = fz_timer_get(enemy->timer_sneaking); if (enemy->dir > 0) { DrawTextureRec(game->assets.entities, texture_rect(enemy->stunned ? frame_sneaking : frame_walking, 8, PLAYER_WIDTH, PLAYER_HEIGHT), pos, WHITE); } @@ -220,7 +220,7 @@ void enemy_kill(enemy_t *enemy, game_t *game) { } void enemy_free(enemy_t *enemy) { - timer_free(enemy->timer_walking); - timer_free(enemy->timer_sneaking); + fz_timer_free(enemy->timer_walking); + fz_timer_free(enemy->timer_sneaking); free(enemy); } diff --git a/src/enemy.h b/src/enemy.h @@ -1,31 +0,0 @@ -#pragma once - -typedef struct Enemy enemy_t; - -#include "game.h" -#include "util.h" - -typedef enum { - ENEMY_TEST, -} enemy_e; - -struct Enemy { - pos_t pos; - enemy_e type; - bool on_ground; - float velocity; - float gravity; - int dir; - bool stunned; - bool frozen; - int frozen_timer; - float fall_height; - timer_t *timer_walking; - timer_t *timer_sneaking; -}; - -enemy_t *enemy_create(pos_t pos, enemy_e type); -void enemy_update(enemy_t *enemy, game_t *game); -void enemy_draw(enemy_t *enemy, game_t *game); -void enemy_kill(enemy_t *enemy, game_t *game); -void enemy_free(enemy_t *enemy); diff --git a/src/entity.c b/src/entity.c @@ -1,8 +1,8 @@ #include <stdlib.h> -#include "entity.h" -#include "enemy.h" -#include "gate.h" +#include "../include/entity.h" +#include "../include/enemy.h" +#include "../include/gate.h" entity_t *entity_create(entity_e type) { entity_t *entity = malloc(sizeof(entity_t)); diff --git a/src/game.c b/src/game.c @@ -2,14 +2,14 @@ #include <stdlib.h> #include <string.h> -#include "libs/raylib.h" -#include "entity.h" -#include "game.h" -#include "tile.h" -#include "util.h" -#include "player.h" -#include "const.h" -#include "level.h" +#include "../lib/raylib.h" +#include "../include/entity.h" +#include "../include/game.h" +#include "../include/tile.h" +#include "../include/util.h" +#include "../include/player.h" +#include "../include/const.h" +#include "../include/level.h" game_t *game_create(void) { game_t *game = malloc(sizeof(game_t)); diff --git a/src/gate.c b/src/gate.c @@ -1,14 +1,14 @@ #include <stdlib.h> -#include "entity.h" -#include "gate.h" -#include "const.h" +#include "../include/entity.h" +#include "../include/gate.h" +#include "../include/const.h" gate_t *gate_create(pos_t pos, int enemy_max, int time) { gate_t *gate = malloc(sizeof(gate_t)); gate->pos = pos; gate->enemy_max = enemy_max; - gate->timer_spawn = timer_create(1, time); + gate->timer_spawn = fz_timer_create(1, time); gate->frozen = false; gate->frozen_timer = 0; return gate; @@ -47,14 +47,14 @@ void gate_update(gate_t *gate, game_t *game) { gate->frozen_timer--; } // handle spawning - timer_update(gate->timer_spawn); + fz_timer_update(gate->timer_spawn); int enemies_len = 0; for (int i = 0; i < game->entities_len; i++) { if(game->entities[i].type == ENTITY_ENEMY) { enemies_len++; } } - if (timer_check(gate->timer_spawn) && enemies_len < gate->enemy_max) { + if (fz_timer_check(gate->timer_spawn) && enemies_len < gate->enemy_max) { game->entities = realloc(game->entities, sizeof(entity_t) * (game->entities_len + 1)); enemy_t *enemy = enemy_create((pos_t) { .x = gate->pos.x + (TILE_WIDTH - ENEMY_WIDTH) / 2.0, diff --git a/src/gate.h b/src/gate.h @@ -1,19 +0,0 @@ -#pragma once - -typedef struct Gate gate_t; - -#include "game.h" -#include "util.h" - -struct Gate { - pos_t pos; - int enemy_max; - timer_t *timer_spawn; - bool frozen; - int frozen_timer; -}; - -gate_t *gate_create(pos_t pos, int enemy_max, int time); -void gate_update(gate_t *gate, game_t *game); -void gate_draw(gate_t *gate, game_t *game); -void gate_free(gate_t *gate); diff --git a/src/level.c b/src/level.c @@ -1,10 +1,10 @@ #include <stdlib.h> -#include "enemy.h" -#include "level.h" -#include "const.h" -#include "tile.h" -#include "entity.h" +#include "../include/enemy.h" +#include "../include/level.h" +#include "../include/const.h" +#include "../include/tile.h" +#include "../include/entity.h" const char *LEVEL_MAP_1 = { "........................" diff --git a/src/main.c b/src/main.c @@ -1,13 +1,17 @@ #include <stdio.h> #include <stdlib.h> #include <signal.h> -#include <execinfo.h> #include <unistd.h> #include <time.h> -#include "game.h" -#include "const.h" -#include "libs/raylib.h" +#include "../include/game.h" +#include "../include/const.h" +#include "../lib/raylib.h" + +#if defined(PLATFORM_WEB) + #include <emscripten/emscripten.h> +#else +#include <execinfo.h> void handle_segfault(int signal) { void *list[10]; @@ -16,24 +20,35 @@ void handle_segfault(int signal) { backtrace_symbols_fd(list, size, STDERR_FILENO); exit(1); } +#endif + +game_t *game = NULL; + +void do_update(void) { + game_update(game); + game_draw(game); +} int main(void) { printf("PID: %d\n", getpid()); time_t t; srand((unsigned) time(&t)); - struct sigaction sigint_action; - sigint_action.sa_handler = handle_segfault; - sigint_action.sa_flags = 0; - sigemptyset(&sigint_action.sa_mask); - sigaction(SIGSEGV, &sigint_action, NULL); InitWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "Freezo"); - game_t *game = game_create(); + game = game_create(); SetTargetFPS(60); SetExitKey(0); - while (!game->quit && !WindowShouldClose()) { - game_update(game); - game_draw(game); - } + #if defined(PLATFORM_WEB) + emscripten_set_main_loop(do_update, 0, 1); + #else + struct sigaction sigint_action; + sigint_action.sa_handler = handle_segfault; + sigint_action.sa_flags = 0; + sigemptyset(&sigint_action.sa_mask); + sigaction(SIGSEGV, &sigint_action, NULL); + while (!game->quit && !WindowShouldClose()) { + do_update(); + } + #endif CloseWindow(); game_free(game); return 0; diff --git a/src/menu.c b/src/menu.c @@ -1,11 +1,11 @@ #include <stdlib.h> -#include "libs/raylib.h" -#include "menu.h" -#include "util.h" -#include "const.h" -#include "game.h" -#include "level.h" +#include "../lib/raylib.h" +#include "../include/menu.h" +#include "../include/util.h" +#include "../include/const.h" +#include "../include/game.h" +#include "../include/level.h" menu_t *menu_create(void) { menu_t *menu = malloc(sizeof(menu_t)); @@ -16,6 +16,9 @@ menu_t *menu_create(void) { void menu_update(menu_t *menu, game_t *game) { UNUSED(menu); UNUSED(game); + if (IsKeyPressed(KEY_ESCAPE)) { + game->state = STATE_GAME; + } if (IsKeyPressed(KEY_W)) { if (menu->idx > 0) { menu->idx--; diff --git a/src/player.c b/src/player.c @@ -1,12 +1,12 @@ #include <stdlib.h> #include <math.h> -#include "player.h" -#include "const.h" -#include "tile.h" -#include "util.h" -#include "entity.h" -#include "effect.h" +#include "../include/player.h" +#include "../include/const.h" +#include "../include/tile.h" +#include "../include/util.h" +#include "../include/entity.h" +#include "../include/effect.h" player_t *player_create(pos_t pos) { player_t *player = malloc(sizeof(player_t)); @@ -23,8 +23,8 @@ player_t *player_create(pos_t pos) { .fall_height = 0.0, .held_enemy = NULL, .moving = false, - .timer_walking = timer_create(9, 4), - .timer_sneaking = timer_create(9, 8), + .timer_walking = fz_timer_create(9, 4), + .timer_sneaking = fz_timer_create(9, 8), .target_entity = NULL, .shooting_distance = PLAYER_SHOOTING_RANGE, }; @@ -356,20 +356,20 @@ void player_update(player_t *player, game_t *game) { } // update timer if (player->on_ground && player->moving) { - timer_update(player->timer_walking); - timer_update(player->timer_sneaking); + fz_timer_update(player->timer_walking); + fz_timer_update(player->timer_sneaking); } else { - timer_reset(player->timer_walking); - timer_reset(player->timer_sneaking); + fz_timer_reset(player->timer_walking); + fz_timer_reset(player->timer_sneaking); } } void player_draw(player_t *player, game_t *game) { pos_t pos = pos_snap(player->pos); int frame = (player->sneaking || player->shooting) - ? timer_get(player->timer_sneaking) - : timer_get(player->timer_walking); + ? fz_timer_get(player->timer_sneaking) + : fz_timer_get(player->timer_walking); if (player->damage_timer / 4 % 2 == 0) { if (player->sneaking) { if (player->dir > 0) { @@ -400,7 +400,7 @@ void player_draw(player_t *player, game_t *game) { } void player_free(player_t *player) { - timer_free(player->timer_walking); - timer_free(player->timer_sneaking); + fz_timer_free(player->timer_walking); + fz_timer_free(player->timer_sneaking); free(player); } diff --git a/src/player.h b/src/player.h @@ -1,32 +0,0 @@ -#pragma once - -typedef struct Player player_t; - -#include "util.h" -#include "enemy.h" -#include "game.h" -#include "entity.h" - -struct Player { - pos_t pos; - int health; - bool on_ground; - float velocity; - float gravity; - int dir; - bool sneaking; - bool shooting; - int damage_timer; - float fall_height; - enemy_t *held_enemy; - bool moving; - timer_t *timer_walking; - timer_t *timer_sneaking; - entity_t *target_entity; - float shooting_distance; -}; - -player_t *player_create(pos_t pos); -void player_update(player_t *player, game_t *game); -void player_draw(player_t *player, game_t *game); -void player_free(player_t *player); diff --git a/src/tile.c b/src/tile.c @@ -1,9 +1,9 @@ #include <stdlib.h> -#include "entity.h" -#include "tile.h" -#include "const.h" -#include "util.h" +#include "../include/entity.h" +#include "../include/tile.h" +#include "../include/const.h" +#include "../include/util.h" /* ########################################################################## */ /* # Tile # */ diff --git a/src/util.c b/src/util.c @@ -1,22 +1,22 @@ #include <stdlib.h> #include <string.h> -#include "util.h" -#include "const.h" +#include "../include/util.h" +#include "../include/const.h" -timer_t *timer_create(int frames, int step) { - timer_t *timer = malloc(sizeof(timer_t)); +fz_timer_t *fz_timer_create(int frames, int step) { + fz_timer_t *timer = malloc(sizeof(fz_timer_t)); timer->frames = step * frames; timer->count = 0; timer->step = step; return timer; } -bool timer_check(timer_t *timer) { +bool fz_timer_check(fz_timer_t *timer) { return timer->count == 0; } -void timer_update(timer_t *timer) { +void fz_timer_update(fz_timer_t *timer) { if (timer->count >= timer->frames) { timer->count = 0; } @@ -25,15 +25,15 @@ void timer_update(timer_t *timer) { } } -void timer_reset(timer_t *timer) { +void fz_timer_reset(fz_timer_t *timer) { timer->count = 0; } -int timer_get(timer_t *timer) { +int fz_timer_get(fz_timer_t *timer) { return timer->count / timer->step; } -void timer_free(timer_t *timer) { +void fz_timer_free(fz_timer_t *timer) { free(timer); } diff --git a/src/util.h b/src/util.h @@ -1,42 +0,0 @@ -#pragma once - -#include <stdbool.h> - -#include "libs/raylib.h" - -#define UNUSED(x) (void)(x) - -typedef Vector2 pos_t; -typedef Rectangle rect_t; -typedef struct Timer timer_t; - -#include "game.h" - -struct Timer { - int frames; - int count; - int step; -}; - -timer_t *timer_create(int frames, int step); -bool timer_check(timer_t *timer); -void timer_update(timer_t *timer); -void timer_reset(timer_t *timer); -int timer_get(timer_t *timer); -void timer_free(timer_t *timer); - -pos_t pos_snap(pos_t vec); - -rect_t rect_from_pos(pos_t pos, int width, int height); -bool rect_collide(rect_t a, rect_t b); - -Texture texture_load(char *filename, int scale); -Rectangle texture_rect(int x, int y, int width, int height); - -typedef enum { - TEXT_ALIGNMENT_LEFT, - TEXT_ALIGNMENT_RIGHT, - TEXT_ALIGNMENT_CENTER, -} text_alignment_e; - -void text_draw(pos_t pos, char *text, text_alignment_e alignment, game_t *game);