// when updated, must update serialization, comparison in main.c, and the server
// on input received processing function
typedefstructInputFrame
{
uint64_ttick;
size_tid;// each input has unique, incrementing, I.D, so server doesn't double process inputs. Inputs to server should be ordered from 0-max like biggest id-smallest. This is done so if packet loss server still processes input
V2movement;
uint64_ttick;
V2movement;
inttake_over_squad;// -1 means not taking over any squad
boolaccept_cur_squad_invite;
boolreject_cur_squad_invite;
EntityIDinvite_this_player;// null means inviting nobody! @Robust make it so just sends interact pos input, and server processes who to invite. This depends on client side prediction + proper input processing at the right tick.
inttake_over_squad;// -1 means not taking over any squad
boolaccept_cur_squad_invite;
boolreject_cur_squad_invite;
EntityIDinvite_this_player;// null means inviting nobody! @Robust make it so just sends interact pos input, and server processes who to invite. This depends on client side prediction + proper input processing at the right tick.
boolseat_action;
EntityIDseat_to_inhabit;
V2hand_pos;// local to player transationally but not rotationally unless field below is not null, then it's local to that grid
// @BeforeShip bounds check on the hand_pos so that players can't reach across the entire map
EntityIDgrid_hand_pos_local_to;// when not null, hand_pos is local to this grid. this prevents bug where at high speeds the built block is in the wrong place on the selected grid
boolseat_action;
V2hand_pos;// local to player transationally but not rotationally
// @BeforeShip bounds check on the hand_pos so that players can't reach across the entire map
booldobuild;
enumBoxTypebuild_type;
enumCompassRotationbuild_rotation;
booldobuild;
enumBoxTypebuild_type;
enumCompassRotationbuild_rotation;
}InputFrame;
typedefstructEntity
{
boolexists;
EntityIDnext_free_entity;
unsignedintgeneration;
boolno_save_to_disk;// stuff generated later on, like player's bodies or space stations that respawn.
floatdamage;// used by box and player
cpBody*body;// used by grid, player, and box
cpShape*shape;// must be a box so shape_size can be set appropriately, and serialized
// for serializing the shape
// @Robust remove shape_parent_entity from this struct, use the shape's body to figure out
// what the shape's parent entity is
EntityIDshape_parent_entity;// can't be zero if shape is nonzero
V2shape_size;
// player
boolis_player;
enumSquadpresenting_squad;
EntityIDcurrently_inside_of_box;
enumSquadsquad_invited_to;// if squad none, then no squad invite
floatgoldness;// how much the player is a winner
// explosion
boolis_explosion;
V2explosion_pos;
V2explosion_vel;
floatexplosion_progresss;// in seconds
// grids
boolis_grid;
floattotal_energy_capacity;
EntityIDboxes;
// boxes
boolis_box;
boolalways_visible;// always serialized to the player
enumBoxTypebox_type;
boolis_explosion_unlock;
EntityIDnext_box;
EntityIDprev_box;// doubly linked so can remove in middle of chain
enumCompassRotationcompass_rotation;
boolindestructible;
floatwanted_thrust;// the thrust command applied to the thruster
floatthrust;// the actual thrust it can provide based on energy sources in the grid
floatenergy_used;// battery
floatsun_amount;// solar panel, between 0 and 1
EntityIDplayer_who_is_inside_of_me;
boolexists;
EntityIDnext_free_entity;
unsignedintgeneration;
boolno_save_to_disk;// stuff generated later on, like player's bodies or space stations that respawn.
floatdamage;// used by box and player
cpBody*body;// used by grid, player, and box
cpShape*shape;// must be a box so shape_size can be set appropriately, and serialized
// for serializing the shape
// @Robust remove shape_parent_entity from this struct, use the shape's body to figure out
// what the shape's parent entity is
EntityIDshape_parent_entity;// can't be zero if shape is nonzero
V2shape_size;
// player
boolis_player;
enumSquadpresenting_squad;
EntityIDcurrently_inside_of_box;
enumSquadsquad_invited_to;// if squad none, then no squad invite
floatgoldness;// how much the player is a winner
// explosion
boolis_explosion;
V2explosion_pos;
V2explosion_vel;
floatexplosion_progresss;// in seconds
// grids
boolis_grid;
floattotal_energy_capacity;
EntityIDboxes;
// boxes
boolis_box;
boolalways_visible;// always serialized to the player
enumBoxTypebox_type;
boolis_explosion_unlock;
EntityIDnext_box;
EntityIDprev_box;// doubly linked so can remove in middle of chain
enumCompassRotationcompass_rotation;
boolindestructible;
floatwanted_thrust;// the thrust command applied to the thruster
floatthrust;// the actual thrust it can provide based on energy sources in the grid
floatenergy_used;// battery
floatsun_amount;// solar panel, between 0 and 1
EntityIDplayer_who_is_inside_of_me;
}Entity;
typedefstructPlayer
{
boolconnected;
boolunlocked_bombs;
enumSquadsquad;
EntityIDentity;
EntityIDlast_used_medbay;
InputFrameinput;
boolconnected;
boolunlocked_bombs;
enumSquadsquad;
EntityIDentity;
EntityIDlast_used_medbay;
InputFrameinput;
}Player;
// gotta update the serialization functions when this changes
typedefstructGameState
{
cpSpace*space;
cpSpace*space;
doubletime;
doubletime;// @Robust separate tick integer not prone to precision issues
V2goldpos;
V2goldpos;
Playerplayers[MAX_PLAYERS];
Playerplayers[MAX_PLAYERS];
EntityIDcur_spacestation;
EntityIDcur_spacestation;
// Entity arena
// ent:ity pointers can't move around because of how the physics engine handles user data.
// if you really need this, potentially refactor to store entity IDs instead of pointers
// in the shapes and bodies of chipmunk. Would require editing the library I think
Entity*entities;
unsignedintmax_entities;// maximum number of entities possible in the entities list
unsignedintcur_next_entity;// next entity to pass on request of a new entity if the free list is empty
EntityIDfree_list;
// Entity arena
// ent:ity pointers can't move around because of how the physics engine handles user data.
// if you really need this, potentially refactor to store entity IDs instead of pointers
// in the shapes and bodies of chipmunk. Would require editing the library I think
Entity*entities;
unsignedintmax_entities;// maximum number of entities possible in the entities list
unsignedintcur_next_entity;// next entity to pass on request of a new entity if the free list is empty
EntityIDfree_list;
}GameState;
#define PLAYERS_ITER(players, cur) for(Player * cur = players; cur < players+MAX_PLAYERS; cur++) if(cur->connected)