From d039f3ce0a638db144d39b746ba1ee9daba7fd0a Mon Sep 17 00:00:00 2001 From: Tenari Date: Thu, 26 Mar 2026 07:50:14 -0500 Subject: [PATCH] docs --- README.md | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++ build/.keep | 0 src/client.c | 12 ++++++++++-- src/server.c | 34 +++++++++++++++++--------------- 4 files changed, 83 insertions(+), 18 deletions(-) create mode 100644 build/.keep diff --git a/README.md b/README.md index fc1f8a4..e266631 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,58 @@ +# Space Trading + +**Space Trading** is a computerized board game intended to be played together in a room with family or friends. The "game board" is displayed by the server on the big TV, and each player has their laptop running the client to control the character. + +The goal is to pay off your ship's mortgage first. + +# How To Play + +*This project uses [GCC](https://gcc.gnu.org/) to build. Make sure you have that installed locally first.* + +On every computer that you will need to play, download this repository: +``` +git clone git@github.com:Tenari/space-trading.git +cd space-trading +``` +and then build it: + +MacOSX/unix: +```bash +./make.sh server + +or + +./make.sh client +``` + +Windows (client only): +```bash +./win_make.bat +``` + +The resulting executable binary file will be in the `build` directory. Run it from the unix command line: +```bash +./build/server + +or + +./build/client +``` + +Or, double-click on the windows .exe file. + +--- + +All computers you will use to play must be connected to the same Wi-Fi network. It uses Local Area Networking (LAN) to connect them together. + +1. connect a computer to your main TV/projector screen. This will be your "server." Run the server binary +2. you can press `TAB` on the server to switch between Debug and Map. Map is the main game-view. +3. have each player run their `client` application. It will prompt them for the `Server IP Address`, which should be displayed in the top right corner of the server. +4. Don't bother with secure passwords when logging. The password is just to prevent your brother from trying to login as you. +5. Wait until each player has selected their ship and sees the "Map" tab on their screen. +6. Start playing! + +### ideas + space-trader-multiplayer-boardgame-esque: - projector shows the star-map with everyone's positions diff --git a/build/.keep b/build/.keep new file mode 100644 index 0000000..e69de29 diff --git a/src/client.c b/src/client.c index fee8b53..5075af0 100644 --- a/src/client.c +++ b/src/client.c @@ -1753,7 +1753,7 @@ fn bool updateAndRender(TuiState* tui, void* s, u8* input_buffer, u64 loop_count } else { field = &state->login_state.password; } - if (isAlphaUnderscoreSpace(input_buffer[0])) { + if (isAlphaUnderscoreSpace(input_buffer[0]) || user_pressed_a_number) { field->bytes[state->login_state.field_index] = input_buffer[0]; if (state->login_state.field_index+1 < field->capacity) { state->login_state.field_index += 1; @@ -1765,7 +1765,15 @@ fn bool updateAndRender(TuiState* tui, void* s, u8* input_buffer, u64 loop_count state->login_state.field_index -= 1; field->length -= 1; } - } else if (input_buffer[0] == ASCII_RETURN || input_buffer[0] == ASCII_LINE_FEED) { + } else if (user_pressed_tab) { + state->login_state.selected_field = state->login_state.selected_field == 0 ? 1 : 0; + if (state->login_state.selected_field == 0) { + field = &state->login_state.name; + } else { + field = &state->login_state.password; + } + state->login_state.field_index = field->length; + } else if (user_pressed_enter) { if (state->login_state.selected_field == 0) { state->login_state.selected_field = 1; state->login_state.field_index = 0; diff --git a/src/server.c b/src/server.c index 59946db..1cfc7fc 100644 --- a/src/server.c +++ b/src/server.c @@ -1059,23 +1059,25 @@ fn void* gameLoop(void* params) { } // tick all the star systems (auctions) - StarSystem* sys = NULL; - Range1u64 sys_range = LaneRange(STAR_SYSTEM_COUNT); - for (u32 i = sys_range.min; i < sys_range.max; i++) { - sys = &state.map[i]; + if (player_count > 0) { // don't bother until there's actually a player + StarSystem* sys = NULL; + Range1u64 sys_range = LaneRange(STAR_SYSTEM_COUNT); + for (u32 i = sys_range.min; i < sys_range.max; i++) { + sys = &state.map[i]; - // tick the auction price - u32 grace_period_ends_at = sys->auction.started_at + (GOAL_GAME_LOOPS_PER_S * 3); - bool is_auction_still_running = sys->auction.finished_at == 0; - bool is_auction_grace_period_finished = state.frame > grace_period_ends_at; - if (is_auction_still_running && is_auction_grace_period_finished) { - f32 initial_price = COMMODITIES[sys->auction.type].price * AUCTION_PRICE_START_MULTIPLE; - f32 t_sec = ((f32)state.frame - (f32)grace_period_ends_at) / (f32)GOAL_GAME_LOOPS_PER_S; - // t is in minutes - f32 t = t_sec / 60; - f32 decay = -0.50 * t; - f32 floor_price = COMMODITIES[sys->auction.type].price * 0.9; - sys->auction.price = Max((initial_price * pow(EULERS_E, decay)), floor_price); + // tick the auction price + u32 grace_period_ends_at = sys->auction.started_at + (GOAL_GAME_LOOPS_PER_S * 3); + bool is_auction_still_running = sys->auction.finished_at == 0; + bool is_auction_grace_period_finished = state.frame > grace_period_ends_at; + if (is_auction_still_running && is_auction_grace_period_finished) { + f32 initial_price = COMMODITIES[sys->auction.type].price * AUCTION_PRICE_START_MULTIPLE; + f32 t_sec = ((f32)state.frame - (f32)grace_period_ends_at) / (f32)GOAL_GAME_LOOPS_PER_S; + // t is in minutes + f32 t = t_sec / 60; + f32 decay = -0.50 * t; + f32 floor_price = COMMODITIES[sys->auction.type].price * 0.9; + sys->auction.price = Max((initial_price * pow(EULERS_E, decay)), floor_price); + } } }