# The socket bind address for all net.psforever.services except admin. 127.0.0.1 is the # default for local testing, for public servers use 0.0.0.0 instead. bind = 127.0.0.1 # The public host name or IP address. Used to forward clients from the login # server to the world server. The default value will only allow local connections. public = 127.0.0.1 # Login server configuration login { # UDP listening port port = 51000 # Account usernames that don't exist yet will be automatically created in the # database. Useful for test servers and development testing. create-missing-accounts = yes } # World server configuration world { # UDP listening port port = 51001 ports = [] # The name of the server as displayed in the server browser. server-name = PSForever # How the server is displayed in the server browser. # One of: released beta development server-type = development } # Admin API configuration admin { # TCP listening port port = 51002 # The socket bind address bind = 127.0.0.1 } # Database configuration # Full reference: https://github.com/jasync-sql/jasync-sql/wiki/Configuring-and-Managing-Connections # https://github.com/getquill/quill/blob/master/quill-jasync/src/main/scala/io/getquill/context/jasync/JAsyncContextConfig.scala database { # The hostname of the PostgreSQL server. host = localhost # The TCP port to connect to the database with. port = 5432 # The username to connect to the SQL server with. username = psforever # The password to connect to the SQL server with. password = psforever # The database name to use on the SQL server. database = psforever # The SSL configuration of the database connection. # One of: disable prefer require verify-full sslmode = prefer # The maximum number of active connections. maxActiveConnections = 5 } # Enable non-standard game properties game { instant-action = { # Allow instant action to direct a player to a hotspot-local friendly AMS spawn-on-ams = no # If no ally hotspots can be found during instant action, find a friendly spawn closest to an enemy hot spot third-party = no } # Modify the amount of mending per autorepair tick for facility amenities amenity-autorepair-rate = 1.0 # Modify the amount of NTU drain per autorepair tick for facility amenities amenity-autorepair-drain-rate = 0.5 # Purchases timers for the mechanized assault exo-suits all update at the same time when any of them would update shared-max-cooldown = no # Purchases timers for the battleframe robotics vehicles all update at the same time when either of them would update shared-bfr-cooldown = yes # HART system, shuttles and facilities hart { # How long the shuttle is not boarding passengers (going through the motions) in-flight-duration = 225000 # How long the shuttle allows passengers to board boarding-duration = 60000 } new-avatar { # Starting battle rank br = 1 # Starting command rank cr = 0 } # Certifications to add to every character. Note that they do not become free, their cost is deducted from the # player's certification points. The default base certifications are 0 cost. # Values are `Certification` member names. base-certifications = [ standard_assault, standard_armor, agile_armor ] warp-gates { # When a gating fails, fall back to sanctuary rather than stay in the same zone default-to-sanctuary-destination = yes # When a facility next to a warp gate is captured by one faction, # if the facility on the other side of the intercontinental gate pair is owned by a different faction, # that gate pair becomes a broadcast warp gate for those factions broadcast-between-conflicted-factions = yes } cavern-rotation = { # The number of hours between any given cavern locking and another cavern unlocking, # not the total number of hours between a single cavern locking and unlocking. hours-between-rotation = 3 # How many caverns are unlocked at once during rotations # Pay attention to the logs that a corresponding combinational existence found in zonemaps/lattice.json # Examples: # [a,b,c] with 1 requires 'caverns-a' 'caverns-b' 'caverns-c' # [a,b,c] with 2 requires 'caverns-a-b' 'caverns-b-c' 'caverns-a-c' # [a,b,c] with 3 requires 'caverns-a-b-c' # [a,b,c,d] with 3 requires 'caverns-a-b-c' 'caverns-b-c-d' 'caverns-a-c-d' 'caverns-a-b-d' simultaneous-unlocked-zones = 2 # A list of zone numbers that correspond to the caverns, in a continuous order # in which the caverns are locked and are unlocked. # When left empty, the order of the caverns is traversed as-is provided # For example, for cavern zones with number [23, 24, 25, 26, 27, 28], # the order [23, 24, 26, 23, 24, 25, 26] would eliminate #27 and #28 from the rotation enhanced-rotation-order = [23, 24, 25, 26, 27, 28] # If a cavern rotation is forced by the system, # the system will attempt to advance only to the first possible closing warning message at five minutes # When set, however, the next zone unlock is carried out regardless of the amount of time remaining force-rotation-immediately = false } saved-msg = { # A brief delay to the @charsaved message, in seconds. # Use this when the message should display very soon for any reason. short = { # This delay always occurs fixed = 5 # This delay is applied partially - fixed + [0,delay) variable = 5 } # A delay to the @charsaved message whenever a previous message has been displayed, in seconds. # Used as the default interval between messages. # It should provide assurance to the player even if nothing happened. # Actual database interaction not assured. renewal = { fixed = 300 variable = 600 } # A delay to the @charsaved message # whenever an action that would cause actual database interaction occurs, in seconds. # Actual database interaction not assured. # The variability, in this case, serves the purpose of hedging against other activity by the player # that would trigger the message again in a short amount of time. interrupted-by-action = { fixed = 15 variable = 30 } } # Limits the dispatch of PlayerStateMessage packets from a session to its client. # Specifically, a packet will only be dispatched based on whether # it is to be dispatched over a threshold time after the previous dispatch time. # The delay between packets is determined by a distance between the observer player and the target player. # Only affects PlayerStateMessage. player-draw = { # Minimum number of players within a given region before scaling down the range. # Total population - population threshold = overpopulation population-threshold = 20 # Number of players over threshold before the reduction in range is scaled down. # Population step / overpopulation = range step factor (integer) population-step = 5 # Always send packets regarding target players within the given distance. range-min = 50 # Do not send packets regarding target players beyond this distance. (sq.m) # Treat this as an absolute render distance. range-max = 550 # Number of meters reduced from range based on population count over threshold value. (m) # Range step * range step factor = total distance to remove from actual distance range-step = 25 # The distances above min-range where different delays are allowed before a successful packet must be dispatched. [m] # Test distances against entries to find the last one that is not more than the sample distance. # Use the index of that sample distance from this sequence in the sequence `delays` below. ranges = [150, 300, 400] # The absolute time delay before a successful packet must be dispatched regardless of distance. (s) delay-max = 1500 # The time delays for each distance range before a successful packet must be dispatched. [s] # The index for an entry in this sequence is expected to be discovered using the `ranges` sequence above. # Delays between packets may not be as precise as desired # as the heartbeat of upstream packets are measured in quanta of 250ms usually. # As a consequence, additional entries with proper time spacing will push back the next proper update considerably # while additional entries with insufficient time spacing may result in no change in behavior. delays = [350, 600, 800] } # Don't ask. doors-can-be-opened-by-med-app-from-this-distance = 5.05 # How the experience calculates experience { # The short contribution time when events are collected and evaluated. short-contribution-time = 300000 # The long contribution time when events are collected and evaluated # even factoring the same events from the short contribution time. # As a result, when comparing the two event lists, similar actors may appear # but their contributions may be different. long-contribution-time = 600000 # Battle experience points # BEP is to be calculated in relation to how valuable a kill is worth. bep = { # After all calculations are complete, multiply the result by this value rate = 1.0 # These numbers are to determine the starting value for a particular kill base = { # Black Ops multiplies the base value by this much bops-multiplier = 10.0 # If the player who died ever utilized a mechanized assault exo-suit as-max = 250 # The player who died got at least one kill with-kills = 150 # The player who died was mounted in a vehicle at the time of death as-mounted = 100 # The player who died after having been in the game world for a while after spawning. # Dying before this is often called a "spawn kill". mature = 50 # How long it normally takes for a player who has respawned to naturally lose the status of "green" when being inactive. # See `base.nature`. maturity-time = 30000 } life-span = { # The experience value of a player's lifespan is measured in intervals. # Per interval, after all calculations are complete, multiply the result by this value life-span-threat-rate = 1.0 # The experience value of using certain equipment per interval of time during playtime (consider to be per second). # (key, value) where key is technically the index of an ExoSuitType or an object class id and value is the growth threat-assessment-of = [ { id = 0 value = 1.25 }, { id = 1 value = 1.5 }, { id = 2 value = 2.15 }, { id = 3 value = 1.25 }, { id = 4 value = 1.0 }, { id = 258 value = 10.0 }, { id = 410 value = 0 }, { id = 608 value = 0 } ] # The maximum experience ceiling during playtime based on the use of certain equipment. # (key, value) where key is technically the index of an ExoSuitType or an object class id and value is the maximum max-threat-level = [ { id = 0 level = 2000 }, { id = 1 level = 2000 }, { id = 2 level = 5000 }, { id = 3 level = 2000 }, { id = 4 level = 900 }, { id = 258 level = 0 }, { id = 410 level = 0 }, { id = 608 level = 0 } ] } revenge = { # If player A kills another player B who killed player A just previously, this is the percentage of experience to deposit. # The kill event must have been the exact previous life's death after revive or respawn. # This only applies if experience is set to 0. # Set to zero and experience = 0 to ignore revenge. rate = 0.05 # If player A kills another player B who killed player A just previously, deposit this experience. # The kill event must have been the exact previous life's death after revive or respawn. # Set to zero to reuse the experience value from the previous kill event. default-experience = 0 # When using the experience from the previous kill for revenge bonus, cap the reward at this value. max-experience = 350 } } # Support experience points # The events from which support experience rises are numerous. # Calculation is determined by the selection of an "event" that decides how the values are combined. sep = { # After all calculations are complete, multiply the result by this value rate = 1.0 # When using an advanced nanite transport to deposit into the resource silo of a major facility, # for reaching the maximum amount of a single deposit, # reward the user with this amount of support experience points. # Small deposits reward only a percentage of this value. ntu-silo-deposit-reward = 100 # When the event can not be found, this flat sum is rewarded. # This should not be treated as a feature. # It is a bug. # Check your event label calls. can-not-find-event-default-value = 15 # The events by which support experience calculation occurs. # Events can be composed of three parts: a base value, a per-use (shots) value, and an active amount value. # "Per-use" relies on knowledge from the server about the number of times this exact action occurred before the event. # "Active amount" relies on knowledge from the server about how much of the changes for this event are still valid. # Some changes can be undone by other events or other behavior. # # name - label by which this event is organized # base - whole number value # shots-min - lower limit of use count # - minimum amount of shots required before applying multiplier # shots-max - upper limit of use count # - cap the count here, if higher # shots-cutoff - if the use count exceeds this number, the event no longer applies # - a hard limit that should zero the contribution reward # shots-multiplier - whether use count matters for this event # - when set to 0.0 (default), it does not # amount-multiplier - whether active amount matters for this event # - when set to 0.0 (default), it does not events = [ { name = "support-heal" base = 10 shots-multiplier = 5.0 shots-max = 100 amount-multiplier = 2.0 } { name = "support-repair" base = 10 shots-multiplier = 5.0 shots-max = 100 } { name = "support-repair-terminal" base = 10 shots-multiplier = 5.0 shots-max = 100 } { name = "support-repair-turret" base = 10 shots-multiplier = 5.0 shots-max = 100 } { name = "mounted-kill" base = 25 } { name = "router-driver" base = 15 shots-multiplier = 1.0 } { name = "telepad-use" base = 20 shots-multiplier = 1.0 } { name = "hotdrop" base = 25 } { name = "hack" base = 5 amount-multiplier = 5.0 } { name = "ams-resupply" base = 15 shots-multiplier = 1.0 } { name = "lodestar-repair" base = 10 shots-multiplier = 1.0 shots-max = 100 amount-multiplier = 1.0 } { name = "lodestar-rearm" base = 10 shots-multiplier = 1.0 } { name = "revival" base = 0 shots-multiplier = 15.0 shots-cutoff = 10 } ] } # Command experience points cep = { # After all calculations are complete, multiply the result by this value rate = 1.0 # When command experience points are rewarded to the lattice link unit carrier, # modify the original value by this modifier. llu-carrier-modifier = 0.5 # If a player died while carrying an lattice logic unit, # award the player who is accredited with the kill command experience as long as the time it had been carried longer than this duration. # Can set to Duration.Inf to never pass. llu-slayer-credit-duration = 30 seconds # If a player died while carrying an lattice logic unit, # and satisfies the carrying duration, # award the player who is accredited with the kill command experience. llu-slayer-credit = 200 # The maximum command experience that can be earned in a facility capture based on squad size maximum-per-squad-size = [990, 1980, 3466, 4950, 6436, 7920, 9406, 10890, 12376, 13860] # When the cep has to be capped for squad size, add a small value to the capped value # This is that value # -1 reuses the cep before being capped squad-size-limit-overflow = -1 # When the cep has to be capped for squad size, calculate a small amount to add to the capped value squad-size-limit-overflow-multiplier = 0.2 } # When summing bep to produce facility capture base rewards, multiply the result by this value facility-capture-rate = 0.5 } # The game's official maximum battle rank is 40. # This is an artificial cap that attempts to stop advancement long before that. # After becoming this battle rank, battle experience points gain will be locked. # In our case, we're imposing this because character features can be unstable when above BR24. max-battle-rank = 24 promotion { # Whether promotion versus play is offered at battle rank 1. # Anyone who is currently enrolled in the promotion system remains enrolled during normal game play. # Relenting on the promotion debt back to the reset battle rank is still possible. active = true # This battle rank and any battle ranks of ordinal decrement that allow opt-in to the progression system. broadcast-battle-rank = 1 # This is the minimum battle rank that can be set as part of the promotion system. # Used to escape debt and return to normal play. reset-battle-rank = 5 # This is the maximum battle rank that can be set as part of the promotion system. max-battle-rank = 13 # How much direct combat contributes to paying back promotion debt. # Typically, it does not contribute. battle-experience-points-modifier = 0f support-experience-points-modifier = 3f capture-experience-points-modifier = 1f # Don't forget to pay back that debt. } } anti-cheat { # The distance (squared) threshold that triggers if the reported hit location # of a shot does not match the object being hit's location on the server # One of 1-1000000 (sqrt 10000 = ~100 ingame units) hit-position-discrepancy-threshold = 10000 } network { middleware { # How often between executions of the outbound bundling process # Used for outbound packet arrival triggers packet-bundling-delay = 40 milliseconds # How often between executions of the outbound bundling process # Affects the base value on the timer packet-bundling-delay-multiplier = 1.25 # Pause inbound packet transmission towards the network if the sequence number is out of order # Packets are put aside until the sequence is restored, or this timeout passes in-reorder-timeout = 50 milliseconds # Wait on inbound packets if that packet is a SlottedMetaPacket and the next subslot number is greater than expected # Does not stop the transmission of packets to the server # but dictates how long between requests to the network (client) for missing packets with anticipated subslot numbers in-subslot-missing-delay = 50 milliseconds # How many attempts at resolving missing packets with anticipated subslot numbers in-subslot-missing-attempts = 10 } session { # The maximum amount of time since the last inbound packet from a UDP session # before it is dropped. inbound-grace-time = 1 minute # The maximum amount of time since the last outbound packet for a UDP session # before it is dropped. Can be used as a watchdog for hung server sessions. outbound-grace-time = 1 minute } } development { # List of GM commands made available to everyone # Values are `ChatMessageType` members, for example: [CMT_ADDBATTLEEXPERIENCE, CMT_CAPTUREBASE] unprivileged-gm-commands = [] # List of GM bang commands made available to everyone # Since the commands come in as plain chat preceded by a bang (!) character, values are the names of the commands unprivileged-gm-bang-commands = [] net-sim { # Enable artificial packet unreliability. Used for development testing. # Active equally on upstream and downstream packets. enable = no # The percentage of outgoing and incoming packets that are dropped. loss = 0.02 # The time a packet is buffered before being delivered to simulate delay. # The artificial delay is in addition to any real network latency. delay = 150 milliseconds # The percentage chance that a packet will be ordered randomly in the delay # buffer. If the delay is too small then packets won't be reordered. reorder-chance = 0.005 # If a packet is reordered, the maximum time in the future or the past where # it will randomly appear. reorder-time = 150 milliseconds } } kamon { # Enables reporting of metrics to Kamon.io enable = no environment.service = "PSForever" apm.api-key = "" } sentry { # Enables submission of warnings and errors to Sentry enable = no # Sentry DSN (Data Source Name) dsn = "" } include "akka.conf" include "dispatchers.conf"