When we started building EF-Map, we had an ambitious vision: create the ultimate interactive map tool for EVE Frontier that would exceed the capabilities of the in-game client. But vision alone isn't enough—we needed a structured roadmap to turn ambitious goals into production-ready features.
This post shares our journey from requirements gathering through systematic execution, showing how a well-documented plan enabled us to deliver every feature we set out to build while maintaining code quality, performance, and user experience.
The Power of Structured Requirements
Starting with "Why"
Before writing a single line of code, we documented the purpose of the project. Not just "build a map" but specifically:
- Enhanced map visualization beyond the in-game client (zoom, pan, rotate the universe)
- Efficient point-to-point routing with smart jump range handling
- Region-wide exploration routing for systematic territory scanning
- "Bubble" exploration to find all systems within a radius
- In-game route export via copy-paste into the EVE Frontier client
By articulating clear problems to solve, we created a north star for every technical decision. Features weren't just "nice to have"—they solved specific player pain points.
Functional Requirements as Contracts
We broke down high-level goals into testable functional requirements. Each requirement became a contract: "The system shall do X."
Examples:
- "The system shall display the full EVE Frontier universe map, including all solar systems and their Stargate connections."
- "The system shall generate the most efficient route between a user-specified start and destination."
- "The system shall allow users to mark solar systems with a chosen color and custom text notes, saved locally."
This discipline forced us to think through edge cases early:
- What happens when no route exists?
- How do we prioritize stargates vs ship jumps?
- Where do user annotations persist (client-side? server?)?
Technology Choices: Documented Decisions
Frontend Stack Rationale
We didn't just pick React, TypeScript, and Three.js because they're popular. We documented the reasoning:
- React: Component-based architecture for complex interactive UIs; strong community support; excellent for state-heavy applications
- TypeScript: Static typing catches bugs before runtime; improved IDE support; enhanced maintainability for long-term projects
- Three.js: GPU-accelerated 3D rendering essential for smooth 60 FPS with 8,000+ star systems; extensive WebGL abstraction; proven ecosystem
- Vite: Fast development builds; optimized production output; modern ES module support
Each choice was justified by specific project needs. When facing performance challenges later, we could revisit these decisions with context intact.
The Client-First Architecture
A critical early decision: start client-side only. No backend services, no user databases, no authentication complexity. This kept initial development fast and deployment simple (static hosting on Cloudflare Pages).
But we documented future enhancements that would require backend support:
- Shared intelligence overlays (tribes collaborating on tactical notes)
- Fuel consumption calculations requiring external API data
- Dynamic region coloring based on Smart Gate deployment tracking
By acknowledging these limitations upfront, we avoided premature architecture while keeping the door open for future expansion.
Methodical Execution: Features as Milestones
Incremental Delivery
We didn't try to build everything at once. Instead, we prioritized features by user value and technical risk:
Phase 1: Foundation (August 2025)
- Basic 3D starfield rendering (Three.js scene setup)
- Solar system data loading from JSON
- Zoom/pan/rotate camera controls
- System search with label display
Phase 2: Core Routing (September 2025)
- A* pathfinding algorithm implementation
- Point-to-point routing with jump range support
- Route visualization on map
- System name export for in-game use
Phase 3: Advanced Features (October-November 2025)
- Region exploration routing (visit all systems in a region)
- Bubble exploration (radius-based system collection)
- Scout optimizer (genetic algorithm for multi-waypoint routes)
- Smart Gate integration with blockchain authorization
- User overlay system (color marks, annotations, tribes)
Each phase delivered usable value independently. Players could route simple paths in Phase 2 without waiting for advanced optimization in Phase 3.
Non-Functional Requirements: The Hidden Foundation
While functional features get headlines, non-functional requirements made the difference between a prototype and a production tool:
Performance Target: "The map visualization shall render smoothly at 60 frames per second on a typical desktop GPU."
This simple statement drove critical optimizations:
- Instanced rendering for star systems (1 draw call instead of 8,000)
- Spatial indexing for hover detection (binary search vs linear scan)
- Web Workers for pathfinding (keep main thread responsive)
- Code splitting to reduce initial bundle size by 65%
Usability/Consistency: "The user interface shall adopt themes similar to the in-game client."
This led us to implement:
- Dark and orange color schemes matching EVE Frontier's UI
- Familiar iconography and layout patterns
- Keyboard shortcuts mirroring in-game controls
Players felt immediately at home because the tool respected their existing mental models.
Data Model Decisions: Flexibility Through Planning
Static Data with Additive Layers
We designed the data architecture to be extensible by default:
- Primary data:
map_data.jsonfor static regions/systems/stargates - Smart Gate layer: External blockchain data overlaid additively
- User annotations: Local storage (no server required)
- Tribe marks: Cloudflare KV for shared tactical notes
This layered approach meant we could add features without breaking existing ones. Smart Gates didn't require restructuring the core map data—they simply added new edges to the routing graph.
Loading Strategy: Measure Before Optimizing
Our requirements doc explicitly noted: "The optimal strategy for loading map_data.json will be determined during implementation based on performance testing."
This deferred decision was deliberate. We didn't prematurely split data into chunks. Instead, we:
- Measured initial load performance (8.2 seconds)
- Profiled bottlenecks (JSON parsing, Three.js scene init)
- Applied targeted fixes (SQLite database, spatial indexing)
- Validated improvement (down to 800ms)
By acknowledging uncertainty upfront, we avoided wasting time on speculative optimizations.
Feature Creep Management: The "Future Enhancements" Section
Documenting Ideas Without Committing
As development progressed, players suggested dozens of features:
- "Can you add fuel consumption tracking?"
- "What about showing wormhole connections?"
- "I want to color regions by tribal control!"
Instead of saying "no" or derailing current work, we captured these in the Future Enhancements section of the requirements document:
- ✅ Documented for future reference
- ✅ Validated interest (do multiple users want this?)
- ✅ Maintained focus on current milestones
- ✅ Created a backlog for post-launch iteration
This approach kept the team aligned on delivering what we committed to while respecting community feedback.
Measuring Success: Every Requirement Delivered
The Satisfaction of Completion
As we crossed off requirements one by one, the document became a record of achievement:
- ✅ Interactive 3D map visualization
- ✅ Point-to-point routing with A* and Dijkstra options
- ✅ Region exploration routing
- ✅ Bubble exploration within radius
- ✅ Route export for in-game use
- ✅ Smart Gate integration with blockchain authorization
- ✅ Character linking via wallet connect (SIWE)
- ✅ Search functionality (systems, constellations, regions)
- ✅ User overlay/marking system with tribe sharing
- ✅ Customizable color schemes and themes
- ✅ Toggle options for map elements (gates, annotations, stations)
Every feature in the original requirements document shipped. Zero abandoned. This wasn't luck—it was the result of realistic scoping and disciplined execution.
Performance Targets Met
Non-functional requirements also hit their marks:
- Target: 60 FPS rendering → Achieved: Stable 60 FPS on desktop, 50+ on mobile
- Target: Thematic consistency → Achieved: Dark/orange modes match in-game UI
- Target: Fast initial load → Exceeded: 800ms (90% faster than baseline)
Lessons for Other Projects
What Worked
1. Document the "why" before the "how"
Articulating problems being solved kept us focused when facing technical tradeoffs. We could ask: "Does this solution serve the original goal?"
2. Testable requirements eliminate ambiguity
Functional requirements written as "shall" statements became acceptance criteria. No guessing if a feature was "done."
3. Acknowledge uncertainty explicitly
Documenting deferred decisions (like data loading strategy) prevented premature optimization while signaling areas for future investigation.
4. Incremental delivery builds momentum
Delivering usable features in phases kept users engaged and provided early feedback, enabling course corrections without major rework.
5. Future enhancements capture ideas without derailing focus
A documented backlog respects community input while protecting team bandwidth for committed work.
What We'd Do Differently
Earlier performance baselines: We should have measured load times and frame rates from Day 1, not after noticing problems. Early profiling would have caught spatial indexing needs sooner.
User testing cadence: While we gathered feedback continuously, more structured usability sessions would have surfaced UX issues (like panel layout preferences) earlier.
Automated acceptance tests: Functional requirements begged for automated testing. We relied too heavily on manual QA, slowing validation cycles.
The Payoff: Sustainable Development
Requirements-driven development isn't bureaucracy—it's freedom. By investing upfront in clear documentation, we gained:
- Confidence in saying "no" to scope creep (politely, with "Future Enhancements" as backup)
- Velocity from knowing exactly what to build next (no wasted sprints debating priorities)
- Quality from testable acceptance criteria (features ship when requirements are met, not when time runs out)
- Transparency for stakeholders (community could see our roadmap and hold us accountable)
Most importantly, we finished what we started. In an industry plagued by abandoned features and broken promises, EF-Map delivered every requirement we committed to.
Conclusion: Vision + Structure = Results
Ambitious goals need structure to succeed. EF-Map's journey from "wouldn't it be cool if..." to production tool demonstrates the power of:
- Documenting vision (why this matters)
- Breaking down into testable requirements (what success looks like)
- Choosing technology deliberately (justified by needs)
- Executing incrementally (deliver value early and often)
- Measuring against baselines (data-driven optimization)
If you're building something ambitious, invest the time upfront. Write down what you're solving, who it's for, and how you'll know when you're done. The discipline pays dividends for months to come.
And when you look back at your requirements document with every item checked off? That's a feeling worth chasing.
Related Posts
- Performance Optimization Journey: From 8-Second Loads to 800ms - How we achieved non-functional requirements through measurement-driven optimization
- Smart Gates Phased Rollout: From Vision to Wallet-Authenticated Routing - Six-phase implementation demonstrating incremental delivery
- Smart Assemblies Expansion: Tracking Portable Structures, Totems, and Tribal Markers - Phased approach to expanding feature scope
- Database Architecture: From Blockchain Events to Queryable Intelligence - Technical architecture decisions documented upfront