# How TechManager Handles Technology Research in Unciv

> Discover how the TechManager in Unciv centralizes technology research logic, manages queues, calculates science costs, and handles turn-based advancement including overflow and era transitions.

- Repository: [Yair Morgenstern/Unciv](https://github.com/yairm210/Unciv)
- Tags: internals
- Published: 2026-06-18

---

**The TechManager class in Unciv centralizes all civilization research logic, tracking completed technologies in a HashSet, managing the research queue, calculating science costs with multiple modifiers, and processing turn-based advancement including overflow handling and era transitions.**

The `TechManager` is the core research engine for every civilization in [yairm210/Unciv](https://github.com/yairm210/Unciv), an open-source Android/Desktop reimplementation of Civilization V. Located at [`core/src/com/unciv/logic/civilization/managers/TechManager.kt`](https://github.com/yairm210/Unciv/blob/main/core/src/com/unciv/logic/civilization/managers/TechManager.kt), this class encapsulates how civilizations discover technologies, manage science overflow, and progress through historical eras. All other systems query this manager to check prerequisites, validate unit availability, or determine era-specific bonuses.

## Core Research State Management

### Tracking Completed Technologies

Inside [`TechManager.kt`](https://github.com/yairm210/Unciv/blob/main/TechManager.kt), the manager maintains two critical data structures for completed research. The persistent `techsResearched` is a `HashSet<String>` storing the names of all discovered technologies, while the transient `researchedTechnologies` list holds the actual `Technology` objects for fast runtime access. When checking if a civilization knows a specific technology, the `isResearched(techName: String)` method queries this set in constant time.

### Queueing Future Research

The `techsToResearch` mutable list maintains the civilization's research priority queue. The first element represents the current active research target, accessible via `currentTechnologyName()`. When players select a new technology in the UI, the system simply adds the tech name to this queue. The `canResearchTech(techName: String)` helper validates prerequisites before allowing queue insertion, ensuring the civilization meets all requirements.

## Turn-Based Research Progression

### Processing Science Each Turn

At the end of every turn, [`GameInfo.kt`](https://github.com/yairm210/Unciv/blob/main/GameInfo.kt) invokes `TechManager.endTurn(scienceForNewTurn: Int)` to advance research. This method aggregates multiple science sources:

- Base science generation from cities
- Research agreement bonuses
- Accumulated `overflowScience` from previous discoveries

The combined total feeds into `addScience(science: Int)`, which updates the running total against the current technology's cost.

### Completing Technologies and Triggering Uniques

When accumulated science meets or exceeds the target cost, `addScience` automatically triggers `addTechnology(techName: String)`. This method performs several critical operations:

1. Adds the technology to `techsResearched` and updates `researchedTechnologies`
2. Removes the completed tech from `techsToResearch` (unless it supports continuous research)
3. Invokes `updateTransientBooleans()` to refresh flags like `unitsCanEmbark`, `movementSpeedOnRoads`, and `allTechsAreResearched`
4. Fires all technology-specific uniques and reveals strategic resources
5. Calculates `overflowScience` (capped by `limitOverflowScience`) for the next research target
6. Calls `moveToNewEra()` if the technology advances the civilization's historical period

## Overflow Science and Era Mechanics

### Handling Excess Research

The `overflowScience` field stores surplus research points that exceed a technology's cost. To prevent runaway accumulation, the `limitOverflowScience` property caps overflow based on the next technology's cost. During `endTurn`, uncapped overflow automatically applies to the new research target, ensuring no science is wasted when completing expensive technologies in a single turn.

### Advancing Eras

The `moveToNewEra()` method updates the civilization's era when research crosses chronological thresholds. This triggers era-specific uniques and posts notifications to the player. Additionally, `updateEra()` recalculates the current era based on the highest era among all researched technologies, ensuring the civilization's historical period always reflects its most advanced discovery.

## UI Integration and Automation Helpers

The [`TechPickerScreen.kt`](https://github.com/yairm210/Unciv/blob/main/TechPickerScreen.kt) interface interacts directly with the manager to display available technologies, costs, and remaining turns. When players click a tech button, [`TechButton.kt`](https://github.com/yairm210/Unciv/blob/main/TechButton.kt) adds the selection to `techsToResearch`. For AI and modding support, helper methods like `getRequiredTechsToDestination(targetTech: Technology)` calculate prerequisite chains, while `turnsToTech(techName: String)` estimates completion time based on current science output.

## Code Examples

```kotlin
// Queue a new technology from UI interaction or modding
civInfo.tech.techsToResearch.add("Pottery")

```

```kotlin
// Process end-of-turn science (called by GameInfo.kt)
val scienceGenerated = civInfo.stats.statsForNextTurn.science.toInt()
civInfo.tech.endTurn(scienceGenerated)

```

```kotlin
// Manually inject science for cheats or events
civInfo.tech.addScience(50)

```

```kotlin
// Query current research progress
val currentTech = civInfo.tech.currentTechnology()
val turnsRemaining = civInfo.tech.turnsToTech(currentTech?.name ?: "")

```

```kotlin
// Validate technology ownership for AI decisions
if (civInfo.tech.isResearched("Astronomy")) {
    // Enable astronomy-dependent units or buildings
}

```

```kotlin
// Calculate prerequisite path for long-term planning
val path = civInfo.tech.getRequiredTechsToDestination(
    civInfo.gameInfo.ruleset.technologies["Rocketry"]!!
)

```

## Summary

- **TechManager.kt** serves as the single source of truth for all civilization research state, located in the `com.unciv.logic.civilization.managers` package.
- **State tracking** uses `techsResearched` (HashSet) for persistence and `researchedTechnologies` (transient list) for runtime performance.
- **Research queue** management happens through the `techsToResearch` mutable list, with `currentTechnologyName()` identifying the active target.
- **Cost calculation** in `costOfTech()` applies difficulty, game speed, map size, city count, and unique-based modifiers.
- **Turn processing** occurs via `endTurn()`, which handles science aggregation, research agreements, and overflow application.
- **Completion logic** in `addTechnology()` updates flags, fires uniques, reveals resources, and triggers era transitions through `moveToNewEra()`.
- **Overflow protection** prevents exploit via `limitOverflowScience`, while `updateTransientBooleans()` keeps movement and embarkation flags current.
- **Automation support** includes `isResearched()`, `canResearchTech()`, and `getRequiredTechsToDestination()` for AI pathfinding.

## Frequently Asked Questions

### How does TechManager calculate the science cost for a technology?

The `costOfTech(techName: String)` method applies a multiplicative modifier chain to the base technology cost defined in the ruleset. It factors in game difficulty, game speed percentage, map size multiplier, the civilization's city count, and any unique-based modifiers from buildings or policies. The final integer represents the total science required before `addTechnology()` triggers.

### What happens to excess science when a technology completes?

Excess science beyond the technology's cost becomes `overflowScience`, which is capped by `limitOverflowScience` to prevent stockpiling massive amounts for future expensive technologies. During the next call to `endTurn()`, this overflow automatically applies to the new research target, ensuring efficient science usage across turn boundaries.

### How does the UI communicate with TechManager to change research?

[`TechPickerScreen.kt`](https://github.com/yairm210/Unciv/blob/main/TechPickerScreen.kt) displays the technology tree by reading `civInfo.tech` state. When a player selects a technology, [`TechButton.kt`](https://github.com/yairm210/Unciv/blob/main/TechButton.kt) adds the tech name string to the `techsToResearch` list. The manager immediately updates cost calculations and turn estimates, reflecting the new queue in the UI without requiring a full game state refresh.

### Can mods or scripts directly manipulate research progress?

Yes, the manager exposes several public methods for automation. `addScience(Int)` allows direct injection of science points for custom events or cheats, while `addTechnology(String)` immediately grants technologies bypassing normal cost requirements. Mods can also query `getRequiredTechsToDestination()` to calculate prerequisite chains for AI behavior or victory condition checking.