Skip to content

This repository contains a little Game Authoring Environment for turn based games developed with JavaFx

License

Notifications You must be signed in to change notification settings

Jaxonwht/voogasalad

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

VoogaSalad

A Java program using JavaFX that provides a game authoring environment allowing game designers, people with no programming skills, to build turn-based strategy games, using a variety of visual tools and requiring minimal programming.

Names:

  • Vincent Liu (jl729)
  • Haotian Wang (hw186)
  • Amy Kim (yk154)
  • Natalie Le (nl121)
  • Jonathan Nakagawa (jyn2)
  • Inchan Hwang (ih33)
  • Jason Zhou (jz192)
  • Yunhao Qing (yq50)

Timeline

Start Date: 10/30/2018

Finish Date: 12/9/2018

Hours Spent: ~800

Primary Roles

  • Authoring Environment
    • Vincent Liu : Frontend developer. Created basic front-end layout; Created basic graph with drag and drop functionality; Worked on save and load function for phase graph; Enabled tile generation in the front end;
    • Haotian Wang : Frontend developer. Created the frameworks for front-end and for middle-end integration with back-end. Worked on (de)-serialization, event handling, data passing, convenient features and error handling.
    • Amy Kim : Frontend developer. Worked on phase pane; Enabled players, properties, sound, grid layout; Worked on GUI and convenient features.
  • Game Engine
    • Natalie Le : Backend engine developer. Created the engine/gameplay infrastructure and the social center extension.
    • Jonathan Nakagawa : Frontend engine developer.
  • Authoring Engine
    • Inchan Hwang : Backend authoring engine developer. Worked on the Groovy and Phase part of the authoring engine, game engine, save/load/export from authoring engine, overall integration.
    • Jason Zhou : Backend authoring engine developer. Worked on GameObjectCRUD and various specific game objects such as Entity, Tile and Sound.
    • Yunhao Qing : Backend authoring engine developer. Worked on GameObjeectCRUD and Player component.

Resources Used

Images

Articles

Files used to start the project

  • Authoring: src/frontend/src/authoringInterface/MainAuthoringProgram.java
  • Engine: src/controller/src/launching/GameLauncher.java
  • VM Configuration:

    --add-opens java.base/java.lang.reflect=xstream --add-opens java.base/java.util=xstream --add-opens java.base/java.text=xstream --add-opens java.desktop/java.awt.font=xstream --add-opens javafx.base/com.sun.javafx.collections=xstream --add-opens javafx.base/javafx.beans.binding=xstream --add-opens javafx.base/javafx.beans.property=xstream

Files used to test the project

Back end

  • src/authoring_backend/test/CRUDTest.java : This file tests whether the game object CRUD is functioning correctly.
  • src/authoring_backend/test/GroovyBlockTest.java : This file tests whether the groove components, such as the graph and nodes are working appropriately and whether grooveblock is functioning correctly.
  • src/authoring_backend/test/PhaseSerializationTest.java : This file tests whether serialization of phase is successful.
  • src/authoring_backend/test/SerializationTest.java : This file tests whether serialization of groove is successful with the game sword and arrow.
  • src/authoring_backend/test/ValidationTest.java : This file tests whether validation is running.
  • src/authoring_backend/test/XStreamTest.java : This file tests the XStream.

Front end

  • src/frontend/test/GroovyShellTest.java : This class tests the functionality of the Groovy Shell.
  • src/frontend/test/ImageSelectorTest.java : This class tests wheteher image selector is working.
  • src/frontend/test/SerializationTest.java : This class tests the serialization of CRUD interface.
  • src/frontend/test/SwitchingPaneTest.java : This class tests whether switching pane is successful.
  • src/frontend/test/TestGameData.java : This class tests game data.

Files for error handling

Authoring_backend

  • Authoring Utils
    • src/authoring_backend/src/authoringUtils/exception/DuplicateGameObjectClassException.java : This class handles the exception of having duplicate game object class in the CRUD.
    • src/authoring_backend/src/authoringUtils/exception/DuplicateIdException.java : This class handles the exception of duplicating id being used in the CRUD.
    • src/authoring_backend/src/authoringUtils/exception/GameObjectClassException.java : This class is extended by specific game object class exception.
    • src/authoring_backend/src/authoringUtils/exception/GameObjectClassNotFoundException.java : This file handles the exception of calling a game object class that is not found.
    • src/authoring_backend/src/authoringUtils/exception/GameObjectInstanceException.java : This class is extended by specific game object instance exception.
    • src/authoring_backend/src/authoringUtils/exception/GameObjectInstanceNotFoundException.java : : This file handles the exception of calling a game object instance that is not found.
    • src/authoring_backend/src/authoringUtils/exception/GameObjectTypeException.java : This class hanldes exception of game object type conflict.
    • src/authoring_backend/src/authoringUtils/exception/IdException.java : This class is extended by specific id class exception.
    • src/authoring_backend/src/authoringUtils/exception/InvalidGameObjectClassException.java : This file handles invalid game object class exception.
    • src/authoring_backend/src/authoringUtils/exception/InvalidGameObjectInstanceException.java : This file handles invalid game object instance exception.
    • src/authoring_backend/src/authoringUtils/exception/InvalidIdException.java : This class handles invalid id exceptions.
    • src/authoring_backend/src/authoringUtils/exception/InvalidOperationException.java : This file handles invalid operations on id in CRUD.
    • src/authoring_backend/src/authoringUtils/exception/InvalidPointsException.java : This class handles invalid point exception in CRUD.
    • src/authoring_backend/src/authoringUtils/exception/TurnNotFoundException.java : This class handles the exception of a certain turn not found in CRUD.
  • Groovy
    • src/authoring_backend/src/groovy/graph/blocks/core/ArgNumberMismatchException.java : This class handles argument number mismatch exception.
    • src/authoring_backend/src/groovy/graph/blocks/small_factory/ListParseException.java : This class handles list parse exception.
    • src/authoring_backend/src/groovy/graph/blocks/small_factory/MapParseException.java : This class handles all kinds of map parse exception.
    • src/authoring_backend/src/groovy/graph/blocks/small_factory/NoSuchPropertyException.java : This class handles no such property exception.
    • src/authoring_backend/src/groovy/graph/blocks/small_factory/ReferenceParseException.java : This class handles reference parse exception.
    • src/authoring_backend/src/groovy/graph/PortAlreadyFilledException.java : This class handles port already filled exception.
    • src/authoring_backend/src/groovy/graph/PortNotConnectedException.java : This class handles port not connected exception.
    • src/authoring_backend/src/phase/NamespaceException.java : This class handles name space exceptions.

Controller

  • src/controller/src/social/UserException.java

Frontend

  • src/frontend/src/authoringInterface/sidebar/RedundantNamingException.java : This file handles duplicate naming exception.
  • src/frontend/src/authoringInterface/subEditors/exception/IllegalGameObjectNamingException.java : This file handles invalid naming for game objects exception.
  • src/frontend/src/authoringInterface/subEditors/exception/IllegalGeometryException.java : This file handles illegal geometry exception.
  • src/frontend/src/authoringInterface/subEditors/exception/MissingEditorForTypeException.java : This file handles missing editor for type exception.
  • src/frontend/src/runningGame/IllegalSavedGameException.java : This class handles inappropriate saved game exception.
  • src/frontend/src/utils/exception/GridIndexOutOfBoundsException.java : This class handles grid index out of bound exception.
  • src/frontend/src/utils/exception/NodeNotFoundException.java : This class handles a specific node is not found exception.
  • src/frontend/src/utils/exception/PreviewUnavailableException.java : This class handles preview unavailable excepton.
  • src/frontend/src/utils/exception/UnhandledCoordinatesClassException.java : This class handles coordinates class unhandled exception.
  • src/frontend/src/utils/exception/UnremovableNodeException.java : This class handles a certain node is unremovable exception.
  • src/frontend/src/utils/exception/XMLParsingException.java : This class handles any issue in paring the XML.

Data or resource files required by the project

The user can to customize images for entity, tile and user avatars. The user need to prepare these images and set the appropriate image for respective image objects in building the game.

How to use the program

Authoring Environment: Run the MainAuthoringProgram.java to access the authoring program.

Engine: Run the GameLauncher.java to access the game launcher. Click any game's "Play" button the play the game. Sign in to access social center functionality under the "Social" tag.

Anything else?

Known Bugs

Unimplemented Features

  • Loading player image in the game.
  • Redo and Undo are too difficult with our current framework and we did not manage to finish it before the deadline. However, basic framework (Memento Pattern) is set up in our project

Design decision

  • Initially we were unsure about how to build the authoring engine so the author can build a game with little code. We carefully studied the game TicTacToe and came up with the idea of having a grid and various game objects such as entities and tiles. We later decided to also have players, turns and categories as game objects too. After making the TicTacToe works, we started to think about how to make other games work. Inchan came up with the idea of Groovy, through which all kinds of logic can be converted from graphics such as nodes and lines to codes that can be run. These two components form the foundation of the authoring backend.

Extra features

  • User can connect to social media such as Twitter and share result of playing the game instantly.

  • User can customize background music for the game and also customize sound effect on actions in playing the game.

  • User has a social center where he or she can see all the games he or she has created.

  • Convenient features; Batch mode and detachable tabs.

  • User can save and load the game graphically on the authoring engine; Groovy and Phase nodes are also saved and loaded.

Impression

  • Vincent Liu : VoogaSalad is more challenging compared to the previous 3 projects, Breakout, Cell Society and SLogo. I learnt how to work with a team by using interfaces and I truly feel I can work better in a team setting in the future.

  • Haotian Wang : I have been working on connecting backend and the UI. I enjoyed the process a lot, it is so fun to see how much changes I made and how flexible our codes become after I re-construct the structure of our project. I feel I understand the 'Open For Extension,Closed for Modification' much more after this project.

  • Amy Kim : This was a very big project; I had to debug and test a lot for implementing new features, even it was not a complicated feature. I have been working on the GUI and I really like the experience. Learning how all the UI components work, how the UI components are connected to the back-end and learning how to handle user input were challenging but fun as well.

  • Natalie Le : I had a really great time working on this project. I learned a lot about module dependencies, external libraries, and design patterns like Pub-Sub. My team and I also learned a lot about technical collaboration and best practices for engineering groupwork. It was awesome working with such great teammates!

  • Jonathan Nakagawa : I am truly happy with working on the sole of our program - the game engine frontend. I spent some time on UI as well. I have learnt a lot and I believe the skills and friendship I obtained from the project will last.

  • Inchan Hwang : This project is very challenging but I learnt so much about APIs and Reflection and I truly appreciate the power of JavaFX now! Although it is time-consuming, the project is definitely worth doing. I realise how much I enjoy backend coding and I aspire to be a backend engineer in the future!

  • Jason Zhou : The project is challenging in its concept and design. I learn a lot about APIs, Lambda, and Reflection. I had a great time design and implementing the front end and also learn how to connect the front end and the back end, which is very valuable for me.

  • Yunhao Qing : Building Voogasalad is very time-consuming. I get much more used to using Git as a part of a team through doing this project. I am responsible for authoring engine backend coding and I am very satisfied with working on backend.I learn about how flexibility of codes is important as making changes on flexible codes is much easier and changing codes is what we do all the time.

Tutorial

Game Showcase

  • Goblin vs troll game (Inchan)
  • TicTacToe (Natalie)
  • Connect4 (Yunhao)
  • Reversi (Vincent)
  • Battleship (Haotian)
  • Wack-a-mole (Amy)
  • Minesweeper (Jingchao)

Basics

To author a game, you must first define

  • Grid layout
  • Players
  • Entities
  • Tiles
  • BGM (optional)
  • Phase
  • Win Condition

The best way to learn is through examples!

We're going to create a goblin vs troll game, with a simple goal of eliminating either the king goblin or the queen troll.

Step1. Define grid layout

We define the grid size as 10x10.

Step2. Define players

It's a simple game, and players don't really have special statistics. So we just create two empty players A and B. You don't really have to add images.

Step3. Define entities

The sidebar should be pre-initialized with some basic entities/tiles. Let's delete them. You can edit/delte each item on each category by right-clicking them (if it doesn't immediately pop-up, keep trying).

Be sure to save, and also to make backup versions in case something goes wrong. It's on the menubar File -> Save.

After deleting everything, let's create some entities. We'll need

  • Goblins: swordman, bowman, king
  • Trolls: swordman, shaman, queen

First, we prepare some images for the entities.

#Notice how there are multiple images for each health point. These can be dynamically set through image selector which we'll see soon. #Note that transparent pixels are transparent to mouse clicks as well

Now we're ready to make entities on our authoring environment. Right click Entity from sideview, and press add entry. Fill in the fields EXCEPT for players/image selector/properties, as they'll throw some weird exceptions if you try to set them at this stage.

The goblin king can't attack so it has range 0.

# To remove an image from this window, click the image you want to remove and press delete key from the keyboard.

We now right-click on the created entity from sideview and press edit to add properties and their default values.

As always, save and make backups as you go.

Image Selectors

But we want to display the image that corresponds to the goblins's health. To do so, click on Image Selector button.

#Be sure to do this AFTER creating an entity, and on the editing window.

So this is the GroovyPane on which we need to construct some groovy code out of. In an image selector, we need to return an integer index between 0 and # of images - 1. Then, each goblin instance will select its image depending on the output. By default, the image selector is constructed to return 0.

Also, since this is an image selector, we can use $this function from GameMethods category to refer to each instances that this image selector will take effect on.

Our logic will look something like

#Try to think of it as one of the LISP languages; It'll help. When you're stuck with implementing some logic, message Inchan for help...

Anyways, just exit out of the window when you're done, and press apply on the dialog.

#Even if you cancel from the dialog, your changes on the GroovyPanes will still be there unlike other elements

We repeat this process for all six entity types.

Note that nothing stops you from adding any other properties

Now, we're ready to define tiles!

Step 4: Define tiles

It's very similar to how you'd define entities; But be aware of the fact that if you don't define tiles on a grid cell, any clicks on that grid cell will be ignored by the game engine.

Anyways, we only have one tile for this game.

You can define properties/Image selector on tiles too

Since more than 3 enemies can die on a tile, we have to modify our image selector a bit.

#Unlike Java, $return does NOT terminate the progression of the code; the last $return call will determine the final return value.

We place the tiles by dragging them onto the grid. You can press SHIFT and drag around the grid to generate multiple tiles at once! But becareful since it'll place multiple tiles if you go through that grid multiple times.

Now, we place entities onto the grid as well. You can use the batch placement functionality on entities as well.

Step 5: Define phase (added some more things to make things interesting)

On this step, you'll define what clicks and keypresses mean to your game.

We model "moves" made by players as FSMs. In this game, the "states" are,

a: Beginning of the turn. b: Selected one of my entity. c: Attacked an entity. d: Healed an ally. e: Moved to an empty tile. f: Replicated goblin king. g: Placed the replicated goblin king.

, and at c,d,e,g, the turn goes to the other player, starting at state a.

The transitions are,

a -> b: clicking current player's entity b -> a: pressing ESC b -> c: clicking an enemy entity within attackRange b -> d: (Only when selected = Troll Shaman) clicking an ally entity within healRange b -> e: clicking a empty tile within moveRange b -> f: (Only when selected = Goblin King) pressing SPACE f -> a: pressing ESC f -> g: pressing on a adjacent tile.

So, we create this phase diagram.

And on each transition, we can specify whether this transition should be taken or not. For example, for a->b, there's two conditions.

  1. The clicked object is an entity.
  2. The clicked entity should be the currentPlayer's entity.

on b->c, there are three conditions:

  1. The clicked object is an entity.
  2. The clicked entity should be other player's entity.
  3. The clicked entity should be within selected entity's attack range.

To set these transition conditions, we double click on the edge, and "write" scripts on the groovyPane. These should return a boolean value.

GroovyPane implementing a->b

#The $clicked block represents the last entity/tile that was clicked.

The nodes also contain a script that gets executed when the game transitions to that node. For example, at state b, we must declare a variable selected as the clicked entity. Variables can be declared with $ block on the literal section. All variables are global!

state b

b->a: always true

b->c: 3 conditions as described above

state c: Notice how we have to call toNextPlayer() to pass the turn. To take the game back to state a, we call goto("a")

b->d: clicking current player's entity within heal_range

state d: Making sure the hp doesn't go beyond max_hp.

state b->e: clicking on empty tile within move_range

state e: Movement

You can sneak in a $print block to debug things

To test what we have until now, we disconnect b->f, and hit Run.

Movement works! But why is shaman's hp 1 from the start? Yeah the ordering was fucked; image selector outputs hp-1 but these images have hps 2 and 1.

Ok they can hit each other.

tile.dead++, working smoothly

does the healing work?

Yeahhhh

Ok we now implement Goblin King's replication.

b->f: check if the selected entity has name Goblin_king

On f, we have nothing to do.

f->g: standard check

state g: creating another instance of goblin king at the clicked tile

Now, let's go ahead and test it.

Yeaaahhhh

Step 7:

To specify the ending condition, go to the win condition tab. This script gets executed after every nodes' execution script.

This game ends when

  1. all goblin kings die
  2. the troll queen dies

Simple script to determine the winner

Yeahhhhh

Step 8: BGM (optional)

You can set the background music for the game by clicking Settings > BGM on the menubar.

Random Notes:

  • Changing properties on the sideview will not (sometimes?) alter properties of things out on the grid.
  • The initial order of the players are... randomly intialized. So try to make a symmetric game.
  • Have AT LEAST one item on each ENTITY/TILE/PLAYER category before saving; If you don't have one, the whole category will disappear.

CHEAT to make your life easier

You can pretty much define your own function blocks if you need them; Just add another method on engine.gameplay.GameMethods. The authoring environment will automatically generate the blocks. This is what I did to create block on the winning condition.

So, in a sense, you can literally write methods that represent image selectors, guards, executions, winning conditionss.

About

This repository contains a little Game Authoring Environment for turn based games developed with JavaFx

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published