The document describes InfectNet, a massively multiplayer online strategy game powered by code written by players. It discusses the game's architecture, which includes separate server and client repositories on GitHub. The game uses a domain-specific language for players to write code that gets executed on the server. Key aspects of the architecture include entity component systems, action/request queues to handle asynchronous behavior, and various game systems that power different aspects like spawning and movement.
3. WHAT IS IT?
• Massively Multiplayer
• Code-driven (custom DSL)
• Computer Virus Themed
• Pseudo Realtime Strategy Game
4. WORKFLOW
• Version Control git
• Development Flow nvie/gitflow
• Methodology Kanban
• Kanban Board Waffle
• Continuous Integration Travis CI
• Static Analysis Tool Codacy
5. PROJECT REPOSITORIES
PARENT REPOSITORY https://github.com/infectnet/infectnet-parent
Does not contain any code, but description of the common development policies among other
repositories.
SERVER REPOSITORY https://github.com/infectnet/infectnet-server
Hosts the source code of the game server and the game engine.
BROWSER FRONTEND REPOSITORY https://github.com/infectnet/infectnet-browser-frontend
Browser-based frontend for the game.
6. TECHS THAT POWER – THE SERVER
• Build Tool Gradle
• Web Application Framework Spark
• Dependency Injection Dagger 2
• Real Time Communication WebSocket
• DSL Base Language Groovy
• Tesing Framework Spock
9. COMPLETE SEPARATION OF CORE/CONTENT
Core
• Defines interfaces to be
implemented
• Self-contained, can run
without content
• Provides the glue code that
connects different engine
parts
Content
• Implementations of engine
interfaces
• Must be imported into the
engine
• The puzzle parts that fit into
the holes of the engine
13. DOMAIN SPECIFIC LANGUAGE
The basic idea of a domain specific language (DSL) is a computer
language that's targeted to a particular kind of problem, rather
than a general purpose language that's aimed at any kind of
software problem.
Martin Fowler
14. DSL – FEATURE OVERVIEW
• Players can express their intents in a declarative way
• Close to the natural language
• Groovy-based with our own additions
15. 1. SELECT
2. FILTER
3. ACTION
• Select the Entities to operate on with Selectors
• Predefined Selectors are available as basic building blocks
• The players can create their own
• Filter the Entities by some condition
• Can include any script with any return value
• Perform some action on the selected Entities
• Select Entities relative to the current ones
21. FORCES – SANDBOXING
• Code written by the Player must be sandboxed
• It potentially contains illegal actions
• Directly modifying game state quickly leads to catastrophy
• Players must not escape their own context
22. FORCES – DETERMINISM
• Source code execution must be deterministic
• In the same turn each player must see the same state
• Potentially simultaneous execution of player code must not
interfere with each other
23. FORCES – BEHAVIOUR EXPOSURE
• The DSL does not define how to do, just what to do
• The behaviour behind the DSL objects must be put
somewhere
• A behaviour can be altered by non-local aspects
Examples: Area-based spells, Player-level bonus, etc.
24. ENTITY WRAPPERS
• Entities are wrapped into an abstract proxy class called
EntityWrapper
• Each entity type must have its own wrapper
• Actions can be attached to wrappers through traits
26. ACTIONS (OBJECTS)
• Command pattern
• Produced by the EntityWrappers
• Represents something that the Player wants to do
• Stored in the Action Queue (Event Queue pattern)
29. ACTION ONLY SYSTEM
• Observes the Action Queue
• Registers itself as a listener of specific Action types
• When triggered, processes the Action and either
• produces a new Request which will be put in the Request Queue, or
• Determines some factor that blocks the Action
30. WHY DO WE NEED ACTION AND REQUEST?
Action
• DSL-level abstraction
• References the current state
• GETS
• May fail if has illegal
arguments
Request
• Atomic persistent operation
• Packs all information
needed to alter the state
• SETS
• Can be executed 99% times
31. REQUEST ONLY SYSTEM
• Observes the Request Queue
• Registers itself as a listener of specific Request types
• When triggered, executes the Request
• May put a new Request into the Request Queue
32. SYSTEMS
• Can listen to both Queues if they want to
• Include most of the logic that powers the game
• Can be as granular as they should be (separation of concerns)
34. ENTITY
• We need a common base class to handle game objects
• But game objects are very heterogenous (behaviour, attributes)
• Let’s create an inheritance tree!
• The tree quickly becomes unmanageable, as DIT increases
35. ENTITY
• Let’s use the Component pattern instead
• Entities become component bags
• If a specific component is not necessary for an Entity, Null Object
pattern can be used
• Only attributes should be stored in components, behaviour is in
the Systems
37. TYPECOMPONENT
• We’ve thrown out inheritance and have only one type
• How to create Entities with the same attributes and behaviour?
• Component pattern comes to the rescue!
• Type Object pattern
38. TYPECOMPONENT
• Abstract class
• The only abstract method is the one that’s interesting
• It’s actually a constructor method for Entities of a given type
• Basically we’ve created our own type system in Java
39. TYPECOMPONENT
• Components store the attributes, but how do TypeComponent
determine the behaviour?
• TypeComponent to EntityWrapper mapping
• Handled by EntityWrapperRepository
40. WORLD
• A big tilemap with two possible tile types:
• CAVE
• ROCK
• Backing storage can be implemented in any way
• Only implementation by now uses a two dimensional array
42. WORLD GENERATION
• Procedural map generation extends the lifetime of the game
• Nobody wants to create 1000x1000 tilemaps manually
• Multiple possible strategies
• Cellular Automaton
• Perlin Noise
• Voronoi Diagram based generation
43. CELLULAR AUTOMATON
• Everybody knows: Game of Life
• Alive and dead cells correspond to CAVE and ROCK
• Multiple steps/iterations
• Can be easily adjusted through the rules and number of steps
44. PATHFINDING
• Classic AI problem
• Performance critical part of the game
• Relaxed A* algorithm is used
• Suboptimal path is provided
• Runs faster than the normal A*
46. GAME LOOP
• An infinite loop
• Initiates player code execution and then publishes the state
changes of the World and the Entities
• Uses a fixed tick time with a ScheduledExecutorService
• Reschedules itself on the Executor when finished