# CompSci 308: Final Project Design Review
### Name: Sumer Vardhan (sv110)
> This is the link to the [assignment](http://www.cs.duke.edu/courses/compsci308/current/assign/04_final/):
## Overall Design
At the highest level, our Tower Defense game authoring program can be broken up into the following three sub-parts:
1. Game Authoring Environment - Responsible for implementing the GUI that the user interacts with to select settings for the various flexible elements of our game engine that can be set up as per the needs of the game. Responsible for representing these 'settings' in an XML file that can be read by the engine directly - i.e there is an inherent dependancy here - the player must produce a correctly formatted XML.
2. Game Engine - Responsible for instantiating objects that represent, at the highest level, the various levels of the game, at a level deeper, the sprites, waves and action condion pairs that exist for that level, and at a level further deeper, the various strategies implemented by each sprite that gives it its functionality. It must then manage these objects by modifying their state as necessary (i.e as per the physics defined within the engine as well as the actions that may be mandated as per a fulfilled condition) each time the Player calls on the execute API method of the engine, passing it the time elapsed in that 'step'.
3. Game Player - Responsible for displaying the functioning game by tying the GAE and engine together. It instantiates the engine with the correct XML file passed to it by the GAE, and then calls on the engine's API methods to access the static and dynamic state of the game - including things like title, resources, available sprites for placing on the screen (TOWER type sprites) as well as the actual states of all the on screen sprites.
The program begins its execution in the Bus class, which sets up a scene that is then handed off to the GAE if the user selects "New Game", or to the Player if the user chooses to load in an existing XML.
If the user selects the "New Game" option, the bus sets the scene to that of the GAE, and the user is able to input the various variable elements of their game. While they are doing this, each time they submit a value or option, it is written into an XML file by an approporiate call to the XMLCreator API, and finally when they submit, the XML file is saved to a default path within the project directory by calling XMLCreator.saveFile(). The scene is switched back to the starting scene where the user can now "Load Game" using the XML file they have created. When they do this, the Bus instantiates a new Player instance, passing it the chosen XML file.
The Player instantiates all the various elements that help it present its UI to the user, and also instantiates the Engine with the XML file passed by the GAE through the Bus class. The engine parses the XML file and does all necessary instantiation of backend objects automatically upon instantiation. The Player can access the getters of the engine object to directly query some basic static state variables, like Level Title and Level Sound Track. It can also get an instance of the engine's ActionsProcessor class, which allows the Player to 'tell' the engine when the Player makes a change to game state - as of now this just includes putting a tower down (Since all other game state changes are internally dictated by the engine). Level Lives and Resources etc. as well as a list of onScreenSprite objects are encapsulated within a GameSceneObject object that is returned by the engine on calling its execute method, specifying the time elapsed since the last 'step'. The player animates the game by setting up a game loop using JavaFX that initializes a new level when engine.didLevelSwitch() returns true. Every other step, it calls the execute method on the engine object, and uses the returned game scene object to obtain the current on screen sprite objects as well as the current values of the resources (Coins and health for now). It passes these values to the update method of its PlayerVisualization object, which creates a new DisplayScreen object to display the current frame of the game (i.e the snapshot of sprites at their current positions at that instant) as well updates the values of the displayed resources.
In our game architecture environment, a game is completely represented by an XML file as well as the associated image files specified within it that determine the visual look of each sprite, as well certain other visual elements like the background image. To create a new game, all that needs to be done is create a correctly formatted XML file, and this can be done by using the GUI provided by the GAE.
The design is independent of the Tower Defense genre in a few ways:
* Each on screen character is represented as a sprite, rather than as something more concrete like towers and enemies. Further, the sprites inherit their functionality by implementing certain strategies. This allows for new sprite functinalities to be added very easily by specifying new Strategies that the sprites can implement.
* The GAE allows a very abstract path to be created using any number of straight lines. This allows paths to not be limited to just simple rectangular or circular paths characteristic of Tower Defense games. A path can take any shape
The design limits us to Tower Defense Games in a few ways too:
* The player expects that it will be displaying at least one TOWER that can be placed onto the screen
* The game assumes that there will be some element of enemies that follow a specific path. Enemies cannot move independent of a path, though implementing this would just be a matter of implementing a Stratey other than DirectedPathMovement for sprite movement.
* The current Actions and Coniditions that have been implemented are very Tower Defense specific, but new Action Condition pairs can be implemented easily in the engine that specify new behvior on certain conditions being fulfilled.
## Your Design
I implemented the Player class and re-designed most of the PlayerVisualization class. At a high level, the goal of my design was to remain as modular from the design of the GameAuthoringEnvironment and the Engine as possible. This way, even if a complete overhaul of the rest of the project was required to add on new features, the Player would remain capable of displaying a game as instructed by the engine through the contract of a sprite list that contains sprites specifying their Archetype, a position in the xy plane as well as an image to represent them. Another goal was to allow an extremely simple entry point for the GAE in order to allow easy live game editing as well as loading up a new game from scratch. The idea was that a Player object, on instantiation, automatically instantiates all its required components as well as an instance of the engine. The game is completely ready to be played. Now, after some live game editing, the GAE can easily pass control back to the instantiated player object, which can make the necessary calls to the engine to reflect changes made. If the user wants to create a new game from scratch, the GAE can just instantiate a new Player object, which will reset everything by instantiating a new Engine object.
To accomplish these goals, the Player class instantiates the engine, and then instantiates the PlayerVisualization class with the necessary Player and Engine state values as parameters. It then sets up the game loop which does two things:
1. If the engine signals a level switch through a call to its API method didLevelSwitch(), Player calls setNewLevel() on its PlayerVisualization object.
2. Otherwise, it calls the engine API method execute followed by PlayerVisualization's update method, passing it the Object object's fields onScreenSprites, lives and resources.
PlayerVisualization instantiates all the UI elements of the Player, and coordinates them, allowing for a simple API call to update to update the entire UI.
The biggest design challenge I took on is definitely the one I described above. The only dependency of the player is in the external APIs of the Engine and the GameSceneObject. The Player class handles both of these dependencies, and does not pass them on to PlayerVisualization.
## Flexibilty
I was most involved with the external API of the Player class and the internal API of the PlayerVisualization class.
To run a new game on our program, the GAE must simply instantiate the Player class with an XML file as a parameter. Internally, the PlayerVisualization class handles all the UI elements of the Player, while the Player class communicates with the engine through its APIs to pass PlayerVisualization the values it needs.
The division of the gameplayer package into Player and PlayerVisualization conceptually separates engine interaction and Player UI creation. The Player handles the former, and PlayerVisualization the latter. Adding new elements to the UI is as simple as creating a helper method in PlayerVisualization to set it up, be it from an existing JavaFX class or one added into the gui package, and add it to some section of the Pane. Any changes in how information has to be received from the engine are limited to the Player class, and therefore a change in the engine does not disrupt the entire gameplayer code, only a very small, control portion (and the Player inherently does not depend on the GAE in any direct way).
## Alternate Designs
Initially, the Engine API was extremely complicated requiring instantiation of SpriteFactories and StrategyFactories and SpriteManagers and so on. The idea behind this was allowing the player as much internal control over the engine as possible while keeping the engine encapsulated. We realized that this would tie the Engine and Player together too closesly. Changes in the engine would heavily affect the implementation of the player if it needed to instantiate managers differently or their APIs changed. The API of the engine evolved into an extremely minimal one that offered only getters and one method call to execute to run the game through a step of some elapsed_time number of seconds.
## Conclusions
The best feature of our design is the flexibility of the game engine to take on new additions, coupled with the ability of the rest of the program to not need any changes due to the extremely limited Engine API, and its being handled by one small control class, Player.
The worst feature of our design is the innate connection between the GAE and the engine in the fact that the GAE must produce a very specifically formatted file, as per the engine's requirements. It is relatively straightforward for the engine to parse new values and the GAE to add them however, as there is a respective class for each of those things that handles the logic in simple, contained API methods.
As a subgroup, we were unable to implement error handling but ideally would have handled all game engine and player related errors. We are currently throwing them to the GAE. We were also unable to implement any tests on time and should have followed test driven development protocol. It would have saved us time in the long run and would have resulted in a more complete final project.
My biggest strength as a coder is being able to read other people's code quite well. I always considered it a daunting task, and found that I really learned how to do it well over the course of this semester.
My biggest weakness as a coder is overthinking design decisions to unproductive lengths and then ending up settling with whatever emerges naturally. I need to find a better balance of analysing and actually trying to implement.
Over the course of this semester, I have tried very hard to patiently read documentation, as well as other people's code. It has been a very rewarding and empowering experience.
{"metaMigratedAt":"2023-06-15T02:34:25.904Z","metaMigratedFrom":"Content","title":"CompSci 308: Final Project Design Review","breaks":true,"contributors":"[{\"id\":\"b7ac107b-48a8-4164-bc3d-5fe6bb7fa3b2\",\"add\":11917,\"del\":15}]"}