Math
Formulas
Production, energy, storage, construction time, flight, fuel, combat, protection, and moon formulas.
This page lists the game formulas. floor rounds down, ceil rounds up, and bps means basis points where 10,000 bps = 100%.
Cost Scaling#
building cost = base cost * building factor ^ current level
standard research cost = base cost * 2 ^ current level
advanced 1.75 research cost = round each resource to nearest 100 after base * 1.75 ^ current levelBinary buildings such as Rift Stabilizer use their base cost and do not scale past the enabled level.
Production#
Production is measured in whole resource units per hour. For a mine at level L, the contract first calculates its raw per-level output and rounds down:
scaled level value(base, L) = floor(base * L * 11 ^ L / 10 ^ L), or 0 at L = 0
raw metal per hour = floor(scaled level value(30, metal level) * metal multiplier bps / 10,000)
raw crystal per hour = floor(scaled level value(20, crystal level) * crystal multiplier bps / 10,000)
raw deuterium per hour = floor(scaled level value(10, deuterium level) * deuterium multiplier bps / 10,000)
metal multiplier bps = 10,000
crystal multiplier bps = 10,000
deuterium multiplier bps = max(0, 12,800 - 20 * planet maximum temperature in °C)Mine level tables and building detail cards show these raw values. They do not include crawlers, Fusion Reactor upkeep, energy shortage scaling, or Solar Satellite effects.
The resource top bar and its Resources popup show live effective production with modifiers applied in this order, rounding down after every basis-point scaling:
crawler boost bps = min(effective crawlers * 2, 5,000)
effective crawlers = min(crawler count, 8 * (metal level + crystal level + deuterium level))
boosted mine output = floor(raw mine output * (10,000 + crawler boost bps) / 10,000)
live effective output = floor(boosted mine output * energy scale bps / 10,000)
fusion deuterium upkeep = ceil(10 * fusion level * 11 ^ fusion level / 10 ^ fusion level)
net deuterium = live effective deuterium output - fusion deuterium upkeepIf energy production is sufficient, the energy scale is 10,000 bps and output is not reduced. The Fusion Reactor upkeep is always charged in full: an energy shortage never reduces it, and net deuterium is negative when the upkeep is larger than the synthesizer's output.
Fusion Reactor Upkeep#
A negative net deuterium rate burns stored deuterium. The reactor runs at full power for as long as the store pays for it:
deficit = fusion deuterium upkeep - live effective deuterium output
seconds paid = floor(stored deuterium * 3,600 / deficit)
deuterium burned = ceil(deficit * elapsed seconds / 3,600), or all stored deuterium once the seconds paid run outOnce the store is empty, the reactor runs only at the share of its upkeep the synthesizer covers on its own, so fusion energy is never free:
unpowered deuterium = live effective deuterium output with no Fusion Reactor energy
fusion share bps = floor(unpowered deuterium * 10,000 / fusion deuterium upkeep)
fusion reactor energy = floor(full fusion reactor energy * fusion share bps / 10,000)
fusion deuterium upkeep = ceil(full upkeep * fusion share bps / 10,000)The energy scale and every mine's output then use that reduced fusion energy, and the synthesizer output left over after the reduced upkeep goes into storage, where the next settlement spends it at full power again. Without a synthesizer the reactor stops. The invite production boost doubles what a planet adds, never the deuterium burned.
Energy#
metal mine demand = scaled level value(10, metal level)
crystal mine demand = scaled level value(10, crystal level)
deuterium synthesizer demand = scaled level value(20, deuterium level)
required energy = metal mine demand + crystal mine demand + deuterium synthesizer demand
solar plant energy = scaled level value(20, solar plant level)
fusion reactor energy = floor(30 * fusion level * (105 + Energy Technology level) ^ fusion level / 100 ^ fusion level)
Solar Satellite energy total = Solar Satellite count * energy per Satellite
produced energy = solar plant energy + fusion reactor energy + Solar Satellite energy total
energy scale bps = 10,000 when produced >= required, otherwise floor(produced * 10,000 / required)
Solar Satellite energy per Satellite = clamp(truncate-toward-zero((maximum temperature + 140) / 6), 1, 65)Solar Satellites therefore change live resource production only by contributing to the energy balance. They never change the raw mine values shown in building details.
Storage And Fields#
Storage buildings increase their resource caps by level. Production stops adding to a resource once it reaches its storage cap. Buildings consume one field per level. Terraformer adds planet fields. Lunar Base adds 3 moon fields per completed level.
Construction, Research, Ship, And Defense Time#
building seconds = max(min queue seconds, floor((metal + crystal) * 3600 / (2500 * (robotics + 1) * 2 ^ nanite * universe speed)))
research seconds = max(min queue seconds, floor((metal + crystal) * 3600 / (1000 * (research lab + 1) * universe speed)))
ship or defense seconds = max(min queue seconds, ceil((metal + crystal) * quantity * 3600 / (2500 * (shipyard + 1) * 2 ^ nanite * universe speed)))Intergalactic Research Network links the highest eligible lab levels for research speed when linked lab levels are available.
Flight Distance, Speed, And Time#
same planet distance = 0 (except same-planet Harvest, which uses local distance 5)
same system distance = 1000 + 5 * position difference
same galaxy distance = 2700 + 95 * system difference
different galaxy distance = 20000 * galaxy difference
travel seconds = 10 + floor(floor(350 * sqrt(distance * 10 / slowest ship speed)) * 100 / (mission speed percent * universe speed))Mission speed options are 100, 90, 80, 70, 60, 50, 40, 30, 20, 10.
Fuel And Cargo#
ship fuel term = quantity * ship fuel * distance * (1 + effective speed / 100) ^ 2
mission fuel = 1 + floor(sum(ship fuel terms) / 35000 + 0.5)
available cargo = total ship cargo - mission fuelAttack loot is limited by available cargo and the target's plunderable resources. Harvest coverage is limited by recycler cargo after fuel.
Combat#
effective attack = base attack * (1 + weapons level * 10%)
effective shield = base shield * (1 + shielding level * 10%)
effective hull = base hull * (1 + armor level * 10%)
combat preview power = effective attack + effective shield + floor(effective hull / 10)
rounds = at most 6
targeted units = min(target unit count, assigned shots)
base hits = floor(assigned shots / targeted units)
extra-hit targets = assigned shots % targeted units
remaining targets receive base hits; only extra-hit targets receive base hits + 1
damage per target = effective attack * its assigned hits
no loss if effective attack <= effective shield / 100
no loss if damage <= effective shield
hull damage = damage - effective shield
destroyed immediately if hull damage >= effective hull
explosion chance bps = floor(hull damage * 10,000 / effective hull) when hull damage > 30% hull
normal defense repair = floor(destroyed defenses * 70 / 100)
small or large shield dome repair = 70% chance to repair one destroyed dome
debris metal = floor((attacker metal losses + defender metal losses) * 30 / 100)
debris crystal = floor((attacker crystal losses + defender crystal losses) * 30 / 100)For example, 100 shots against 99 targets give 98 targets one hit and one target two hits: exactly 100 hits. The two hit groups apply shields, hull thresholds and explosion sampling separately.
Each surviving unit fires once per round before round losses are applied. Shots are distributed across the opposing side by live unit counts. If 100 shots fire into a defender with 80 Rocket Launchers and 20 Light Lasers, about 80 shots target Rocket Launchers and 20 target Light Lasers, with deterministic randomness deciding the remainder. Shields refresh every round, so damage does not carry over between rounds unless it destroys a unit in that round.
Rapidfire Reference#
Rapidfire can create extra shots after the normal shot assignment. A rapidfire factor R is not a guaranteed R shots: every selected shot against an eligible target has a continue chance of (R - 1) / R and a stop chance of 1 / R. An omitted attacker-to-target pair has factor 1 and creates no rapidfire shots. Only ships can generate rapidfire; defenses do not have rapidfire as firing units.
The onchain catalog follows Veydrift's full classic rapidfire matrix, with the Reaper, Pathfinder, and Crawler extensions. Veydrift does not have Espionage Probes, so their probe-only lanes are not represented. All omitted pairs are factor 1.
| Attacker ship | Target ship | Factor `R` |
|---|---|---|
Small Cargo, Light Fighter, Recycler, Colony Ship, Large Cargo, Heavy Fighter, Cruiser, Battleship, Bomber, Destroyer, Battlecruiser, Reaper, Pathfinder | Solar Satellite | 5 |
Same mobile ships | Crawler | 5 |
Heavy Fighter | Small Cargo | 3 |
Cruiser | Light Fighter | 6 |
Battleship | Pathfinder | 5 |
Destroyer | Battlecruiser | 2 |
Battlecruiser | Small Cargo, Large Cargo | 3 |
Battlecruiser | Heavy Fighter, Cruiser | 4 |
Battlecruiser | Battleship | 7 |
Reaper | Battleship | 7 |
Reaper | Bomber | 4 |
Reaper | Destroyer | 3 |
Pathfinder | Light Fighter, Cruiser | 3 |
Pathfinder | Heavy Fighter | 2 |
Dreadstar | Small Cargo, Large Cargo, Recycler, Colony Ship | 250 |
Dreadstar | Light Fighter | 200 |
Dreadstar | Heavy Fighter | 100 |
Dreadstar | Cruiser | 33 |
Dreadstar | Battleship | 30 |
Dreadstar | Bomber | 25 |
Dreadstar | Destroyer | 5 |
Dreadstar | Battlecruiser | 15 |
Dreadstar | Reaper | 10 |
Dreadstar | Pathfinder | 30 |
Dreadstar | Solar Satellite, Crawler | 1,250 |
| Attacker ship | Target defense | Factor `R` |
|---|---|---|
| Cruiser | Rocket Launcher | 10 |
| Bomber | Rocket Launcher, Light Laser | 20 |
| Bomber | Heavy Laser, Ion Cannon | 10 |
| Bomber | Gauss Cannon, Plasma Turret | 5 |
| Destroyer | Light Laser | 10 |
| Dreadstar | Rocket Launcher, Light Laser | 200 |
| Dreadstar | Heavy Laser, Ion Cannon | 100 |
| Dreadstar | Gauss Cannon | 50 |
| Reaper | Ion Cannon | 2 |
In particular, Solar Satellites and Crawlers are targetable, fragile production units rather than rapidfire-proof defensive screens: every mobile ship can chain through them at factor 5, and a Dreadstar has factor 1,250.
For an ideal chain that stays on eligible targets, the unbounded expected number of shots, including the original shot, is R. The contract limits rapidfire to 64 extra-shot chain steps, so that ideal capped expectation is R * (1 - ((R - 1) / R)^65). In a real mixed defender pool, that expectation is not a promise: every chain step retargets by the live target counts and applies deterministic integer rounding.
Exact Onchain Rapidfire Math#
The contract works in basis points (BPS = 10,000) and has MAX_RAPIDFIRE_CHAIN = 64. Let I_k be the incoming shots for chain step k, n_t the live count of target bucket t, and N the number of live target units in the full opposing pool. For every target bucket with factor R > 1:
I_0 = normal shots assigned to the firing ship
weighted_t = I_k * n_t
assigned_t = floor(weighted_t / N)
+ 1 when combatHash(seed, round, side, firing unit, target lane + (k + 1) * 8192) mod N
< weighted_t mod N
continueBps = floor((R - 1) * 10,000 / R)
scaled_t = assigned_t * continueBps
extra_t = floor(scaled_t / 10,000)
+ 1 when combatHash(seed, round, side, firing unit, target lane, 30,000 + k) mod 10,000
< scaled_t mod 10,000
I_(k + 1) = sum(extra_t for every live eligible target bucket)
total extra shots = sum(I_(k + 1)) for k = 0..63combatHash(seed, round, side, firing unit, target lane, stream) is exactly uint256(keccak256(abi.encode(keccak256("veydrift.classic-combat-random-stream.v1"), seed, round, side, firing unit, target lane, stream))).
The battle engine then applies each generated shot with the same attack, shield, hull, and explosion rules as normal shots. A bucket with no live units, no incoming shots, or factor 1 produces zero extra shots. The deterministic combat hash means the same indexed battle seed and state produce the same rapidfire result; it is not wallet- or UI-generated randomness.
Combat example:
Attacker: 1 Cruiser, Weapons 0
Defender: 10 Rocket Launchers, Shielding 0, Armor 0
Cruiser attack = 400
Rocket Launcher shield = 20
Rocket Launcher hull = (2,000 metal + 0 crystal) / 10 = 200
Round 1 normal shots:
1 Cruiser fires 1 shot.
All 10 defender units are Rocket Launchers, so the shot targets a Rocket Launcher.
damage = 400
damage > shield, hull damage = 400 - 20 = 380
380 >= 200 hull, so 1 Rocket Launcher is destroyed.
Rapidfire:
Cruiser has rapidfire 10 against Rocket Launcher.
The selected shot has a 90% chance to add another shot.
If that extra shot occurs, it can destroy another Rocket Launcher using the same damage math.
Defender fire:
The round snapshot fires before losses are applied, so all 10 Rocket Launchers still fire in round 1.
Each Rocket Launcher has attack 80. Their assigned shots target the Cruiser.
Cruiser shield = 50; Cruiser hull = (20,000 metal + 7,000 crystal) / 10 = 2,700.
Each launcher shot deals 80, so each shot passes shield but only deals 30 hull damage.
30 is below 30% of Cruiser hull, so no explosion check happens from a single launcher shot.
After the round:
Destroyed Rocket Launchers are removed, then 70% of destroyed normal defenses repair after battle.
If 2 Rocket Launchers were destroyed and the defender does not win earlier, floor(2 * 70 / 100) = 1 repairs.Protection, Bashing, And Alliance Wars#
Score uses the same contract formula for ranking and attack protection: economy, research, fleet, and defense components contribute to one player score. Below 50,000 score, players are protected from opponents more than 1.5× stronger or weaker. From 50,000 through 499,999, the limit is 10×; at 500,000 and above, score protection does not apply. The bashing window is evaluated by attacker, defender, and planet over 24 hours.
When an alliance declares war, the contract snapshots both alliance total scores and both rosters. Only members in those original rosters receive war exceptions; leaving removes the exception while outside the alliance, and rejoining that same original alliance restores it. If the declaring alliance was weaker or equal at declaration, both original rosters bypass score protection and bashing limits. If it was stronger but no more than 1.5× the declared-on alliance, both original rosters also bypass both limits. If it was more than 1.5× stronger, only original members of the declared-on alliance can bypass score protection and bashing limits when attacking the declaring alliance. An active-war target is marked for verification in target lists; before Confirm is enabled, the mission screen checks the selected attacker, target, frozen roster, and direction against the live war snapshot and explains when normal protection still applies.
Moon Chance And Jump Gates#
moon chance bps = min(floor((metal debris + crystal debris) / 100000) * 100, 2000)
moon destruction bps = min((100 - floor(sqrt(moon diameter km))) * floor(sqrt(dreadstars)) * 100, 10000)
dreadstar destruction bps = min(floor(sqrt(moon diameter km)) * 50, 10000)Jump Gate transfers require both origin and destination moons to have a Jump Gate. A transfer moves ships only, carries no resources, and sets a cooldown on both gates.
