syntax = "proto3";

// Rove
//
// Rove is an asychronous nomadic game about exploring a planet as part of a
// loose community
package roveapi;
option go_package = "github.com/mdiluz/rove/proto/roveapi";

// The Rove server hosts a single game session and world with multiple players
service Rove {
  // Server status
  // Responds with various details about the current server status
  rpc ServerStatus(ServerStatusRequest) returns (ServerStatusResponse) {}

  // Register an account
  // Tries to register an account with the given name
  rpc Register(RegisterRequest) returns (RegisterResponse) {}

  // Send commands to rover
  // Sending commands to this endpoint will queue them to be executed during the
  // following ticks, in the order sent. Commands sent within the same tick will
  // overwrite until the tick has finished and the commands are queued
  rpc Command(CommandRequest) returns (CommandResponse) {}

  // Get radar information
  // Gets the radar output for the given rover
  rpc Radar(RadarRequest) returns (RadarResponse) {}

  // Get rover information
  // Gets information for the account's rover
  rpc Status(StatusRequest) returns (StatusResponse) {}
}

//
// ServerStatus
//

// ServerStatusRequest is an empty placeholder
message ServerStatusRequest {}

// ServerStatusResponse is a response with useful server information
message ServerStatusResponse {
  // The version of the server in v{major}.{minor}-{delta}-{sha} form
  string version = 1;

  // Whether the server is ready to accept requests
  bool ready = 2;

  // The tick rate of the server in minutes (how many minutes per tick)
  int32 tickRate = 3;

  // The current tick of the server
  int32 currentTick = 4;

  // The time the next tick will occur
  string next_tick = 5;
}

//
// Register
//

// RegisterRequest contains data to register an account
message RegisterRequest {
  // The desired account name
  string name = 1;
}

// Account describes a registered account
message Account {
  // The account name
  string name = 1;

  // The account secret value, given when creating the account
  string secret = 2;
}

// RegisterResponse is the response given to registering an account
message RegisterResponse {
  // The registered account information
  Account account = 1;
}

//
// Command
//

// CommandType defines the type of a command to give to the rover
enum CommandType {
  none = 0;
  // Toggles the sails, either catching the wind, or charging from the sun
  toggle = 1;
  // Turns the rover in the specified bearing (requires bearing)
  turn = 2;
  // Stashes item at current location in rover inventory
  stash = 3;
  // Repairs the rover using an inventory object
  repair = 4;
  // Broadcasts a message to nearby rovers (requires data)
  broadcast = 5;
  // Salvages a neighboring dormant rover for parts
  salvage = 6;
  // Transfers remote control into dormant rover
  transfer = 7;
}

// Bearing represents a compass direction
enum Bearing {
  // BearingUnknown an unknown invalid bearing
  BearingUnknown = 0;
  North = 1;
  NorthEast = 2;
  East = 3;
  SouthEast = 4;
  South = 5;
  SouthWest = 6;
  West = 7;
  NorthWest = 8;
}

// Command is a single command for a rover
message Command {
  // The command type
  CommandType command = 1;

  // broadcast - a simple message, must be composed of up to 3 printable ASCII glyphs (32-126)
  bytes data = 2;

  // move - the bearing for the rover to turn to
  Bearing bearing = 3;
}

// CommandRequest describes a set of commands to be requested for the rover
message CommandRequest {
  // The account to execute these commands
  Account account = 1;

  // The set of desired commands
  repeated Command commands = 2;
}

// CommandResponse is an empty placeholder
message CommandResponse {}

//
// Radar
//

// Types of objects
enum Object {
  // ObjectUnknown represents no object at all
  ObjectUnknown = 0;

  // RoverLive represents a live rover
  RoverLive = 1;

  // RoverDormant describes a dormant rover
  RoverDormant = 2;

  // RockSmall is a small stashable rock
  RockSmall = 3;

  // RockLarge is a large blocking rock
  RockLarge = 4;

  // RoverParts is one unit of rover parts, used for repairing and fixing the rover
  RoverParts = 5;
}

enum Tile {
  // TileUnknown is a keyword for nothing
  TileUnknown = 0;

  // Rock is solid rock ground
  Rock = 1;

  // Gravel is loose rocks
  Gravel = 2;

  // Sand is sand
  Sand = 3;
}

// RadarRequest is the data needed to request the radar for a rover
message RadarRequest {
  // The account for this request
  Account account = 1;
}

// RadarResponse describes radar information
message RadarResponse {
  // The range in tiles from the rover of the radar data
  int32 range = 1;

  // A 1D array representing range*2 + 1 squared set of tiles, origin bottom
  // left and in row->column order
  repeated Tile tiles = 2;

  // A similar array to the tile array, but containing objects
  repeated Object objects = 3;
}

//
// Status
//

// StatusRequest is information needed to request rover status
message StatusRequest {
  // The account for this request
  Account account = 1;
}

// Log is a single log item
message Log {
  // The unix timestamp of the log
  string time = 1;

  // The text of the log
  string text = 2;
}

// Vector describes a point or vector in 2D space
message Vector {
  int32 x = 1;
  int32 y = 2;
}

// SailPosition represents the position of the sola sail
enum SailPosition {
  UnknownSailPosition = 0;

  // CatchingWind means the sail is catching the wind and moving the rover
  CatchingWind = 1;

  // SolarCharging means the sail is facing the sun and charging
  SolarCharging = 2;
}

message RoverSpecifications {

  // The name of the rover
  string name = 1;

  // The range of this rover's radar and broadcasting
  int32 range = 2;

  // The capacity of the inventory
  int32 capacity = 3;

  // The maximum health of the rover
  int32 maximumIntegrity = 4;

  // The max energy the rover can store
  int32 maximumCharge = 5;
}

message RoverStatus {

  // The current direction of the rover
  Bearing bearing = 1;

  // The current position of the sails
  SailPosition sailPosition = 2;

  // The items in the rover inventory
  bytes inventory = 3;

  // The current health of the rover
  int32 integrity = 4;

  // The energy stored in the rover
  int32 charge = 5;

  // The set of currently queued commands
  repeated Command queuedCommands = 6;
}

message RoverReadings {
  // Position of the rover in world coordinates
  Vector position = 1;

  // The current wind direction
  Bearing wind = 2;

  // The most recent logs
  repeated Log logs = 3;
}

// StatusResponse is the response given to a status request
message StatusResponse {

  // The static rover information
  RoverSpecifications spec = 1;

  // Current rover status
  RoverStatus status = 2;

  // Current rover readings
  RoverReadings readings = 3;
}