Saturday, 22 November 2014

Github, the Git and The Table State

At the suggestion of a guest at my own place of work, I got myself looking at Git this week. While I admit so far I have been using it as a GUI based, upload my work when I fancy it machine with no branches, I do plan to make fuller use of it soon. While in the super early stages of my concept, I have no need of branches as I am literally treating my gamedev environment as a bouncy house for programming. I'm having fun creating and solving problems and the future is still hazy as to the end product. While I would love for the program to be a success, I have not given myself any promises that this will be a masterpiece. Should my interest head in a different direction based on what I learn during the course of this work, I'm happy to let it go and move on.

While unfinished work is probably the biggest time waste for many programmers, I have taken the view that any time spent working on my project is constructive. Any ideas that make it into the program are successes and the failed ones are lessons.

So, this week I have been working a lot IRL so my time has been spent planning the Table Service aspect of my game. Working with time in Java was an initial hurdle but didn't require too much googling to ensure I was getting the numbers I needed in the format that worked for me. Each guest will be able to generate a set of times which state how long an aspect of their stay will take. John might take two minutes to eat, but Sally might take twenty five. Using this knowledge, the game is able to check for an "all ready" like state, by comparing the state of each guest and acting when all of them match. Using this system requires a set of enum types for the Guest and also for the Table to use as state markers which can be looked at by the other Entities. States in this way happen to be far more effective for the long list of possible states than boolean values had been, as rather than turning one value to true and another to false, the overall state simply switches. This makes a list of instructions much more safe to run as the state can only be one at a time, and no accidentally crosslined booleans will throw me off.


 if(!isActive){  
return;
}
elapsedTime = timeSat + System.currentTimeMillis();

if(state == guestState.sat){
if(startOrderTimer <= 0) startOrderTimer = System.currentTimeMillis();
if(startDrinkOrderTimer <= 0){
startDrinkOrderTimer = System.currentTimeMillis();
}
if(System.currentTimeMillis() - startDrinkOrderTimer > drinkOrderTime){
state = guestState.drinkOrderReady;
}
} else {
return;
}

if(state == guestState.drinkOrderReady){
// when Orders system implemented, fill in order creation here
}


if(state == guestState.drinkOrderTaken){
if(startOrderTimer <= 0){
startOrderTimer = System.currentTimeMillis();
}
if(System.currentTimeMillis() - startOrderTimer >= orderTime){
state = guestState.foodOrderReady;
}
}
In this early example of a guests update method you can see that the state is modified when criteria are met such as an elapsed time and manage progression through a typical service by acting as flags that the table can look for in each guest to create a Task that can then be acted upon by a Staff entity.

The table itself is able to scan through any number of occupying guests in order to check that all guests are in the same state, as shown here.
 private void getGuestStates() {  
if(guests[0].getState() == guestState.sat){
return;
}
Guest.guestState[] states = new Guest.guestState[guests.length];
for (int i = 0; i < guests.length; i++) {
states[i] = guests[i].getState();
}

Guest.guestState temp1 = guests[0].getState();
for (Guest.guestState state : states) {
Guest.guestState temp = state;
if (temp1 == temp) {
temp1 = temp;
} else {
return;
}

System.out.println("Table has determined that all guests' states match: " + state);
}
}
The initial state of guestState.sat will progress from within the Guest so if this state is in place then we save cpu time by exiting the getGuestStates() method. Checking against a fixed array index guests[0] is not a problem as a guests array is not able to have fewer than 1 entry, as 1 is the minimum number of guests in a group (which seems redundant to have a group of 1, but this is simply a container for the guests to proceed into the restaurant queuing system).

Once the basic framework for the states is finished I will make all new table placeholder sprites to help show the state visually. This may be a layered approach using the base table and then an "items on table" type layer such as is used in RPGMaker, but that will come in its own time. I have 3 days booked off this coming week and hope to spend a good chunk of them coding. Until then!

Sunday, 16 November 2014

Mouse Input and UI Ideas

Today I managed to finish implementing a simple mouse tracker for my game. It takes the location of the mouse on the game window, applies the offset made by the "player" movement, and adjusts for the scale of the game (since the game is a small scale and scaled up into a larger window).

An issue I was having was that as the update method for each table is run at 60 Updates per second, the actions taken when the mouse is clicked were also happening 60 times. To avoid this I added a clickLock, which disables a table from being clicked again for a second. The update method then decreases the lock each cycle until it hits zero.

           if(Mouse.getButton() == 1 && clickLock <= 0){  
if(Mouse.getX() + Screen.getxOffset() >= x
&& Mouse.getX() + Screen.getxOffset() < x + sprite.SIZE
&& Mouse.getY() + Screen.getyOffset() >= y
&& Mouse.getY() + Screen.getyOffset() < y + sprite.SIZE){
timer += 300;
clickLock += 60;
}
}

This snippet is my way of debug adding a state change to the table that is clicked. At the moment the tables update based on an increment per update and switched based on time passed in this manner. In future the tables cycle will update state based on the time and the personal preferences of the guests.
Each guest will be created with a set of randomly generated times such as how long it takes them to make an order, to eat and any "sitting and chilling" time after the service ends. These numbers will create some variation between tables as they will not all sit and end in a predictable pattern. If your group consists of two guests and one takes longer to order, they will both have to wait for an order to be placed. If you have a table of four people and they all decide quickly, the amount of time before an order can be made could be much shorter. In many games based on "cafe" or "restaurant" settings, the guests are very copy paste and fall into guest "types". I would rather have a guest be defined by their own set of preferences and also variables such as cash on hand and time available. A guest who is trying to get a quick bite should be seen to be ordering, eating and leaving quicker than a guest who is in for a social meal.

My noteboook, ideas on UI and button themes
My first notebook page was taken up by some brief ideas on how to add buttons to my UI. I had been playing around with MouseListener and when I hit a bump (NOO! Don't run that code nine thousand times a second!) I took some time off to doodle down some ideas. I hadn't given much thought to the buttons layout yet since I started this project off wanting to make an android app with touch controls (and notably smaller screen space for UI). When I began to narrow down what my influences for the game were, I thought about the way those games handled buttons. The left column of my notes tackle how I can keep a status bar accessible at all times for the player to see general information. Things like a clock and a rating, a countdown timer for timed goals, maybe even an income target and percentage to target bar. While some information is useful in all views, I had the idea that it could present slightly tailored information depending on the object or actor in focus. For example, if I click a manager, or a bartender, or a guest I should see different information that relates to their role and state. If i have nothing selected, a rating bar could show my overall rating, for a waiter, their individual performance rating for the day/week/month, and for a guest perhaps a rating on their experience so far.

Keeping this information in the lower left will keep it away from the main action in center screen but not out of the way enough to be a hindrance to glance at. Keeping status related, non-interactive information at the base of the screen should be natural for many users, while any modifiable or quick changing status on the upper portion of the screen.

The right side of the page was a few ideas I had about button types(management, lists, menu edits etc), while the next doodle was an idea I had about using Aura Buttons such as in World of Warcraft and other RPG games to switch between styles of play. For example a moving around mode, an inspection and statistics mode or simply a way to switch between controls relating to staff, management and logistics. This may add a way to switch input without having to find and select certain actor types, and instead control the game as a whole. An example of this could be that in "waiter" mode, you are able to click on flagged tables and service stations to prompt a staff member to act sooner on that task, while in management mode you are able to dish out morale or efficiency buffs to staff and boost the happiness of a group of guests with some fun product knowledge.

Thursday, 13 November 2014

Thinking about input

I've been thinking about input a lot lately as I definitely want to be able to be flexible in my controls. The use of the traditional WASD keys for movement is always going to be a feature when in control of a game avatar, but I would like to have Mouse input form a large part of the core game play too. While the game will be a simulator, I will create opportunities for the player to have direct influence such as placing objects in the environment, selecting other avatars, highlighting objects for inspection etc.

My game design is based on creating a world as interactive as Rollercoaster Tycoon was, with access to menus to control prices, individual guest dialogs, construction and also access to things like staff lists and skills. The restaurant world is not necessarily a fun environment that people aspire to be a part of from afar, in all fairness it is a stressful and tiresome, but managing one and having influence on design, staffing and item names etc will make the experience more engaging.

While the player controlled aspects of the game will ultimately be on the simpler, more holistic side, I would like to have a much beefier simulation running under the hood that advanced players can tap into at will, without having it interfere too much with the core gameplay. The game will hopefully be a good blend of time-management style point and click gameplay, with a rich economic engine that doesn't bog it all down. I have picked up a small notebook for writing down ideas on the go, whenever possible I will try to add pagescans so that you can see my thought processes and doodles!

Tuesday, 11 November 2014

Implementing graphics

Working on my Sim tonight has been a trial. The graphics setup that I have been using is heavily based on the Game Programming videos by TheCherno on You tube. Up until now I have been able to add graphics for the Tables in my gym using a simple render method, but tonight I set out to add a background array of tiles to represent the ground and walls. At first I wanted to figure some of it out on my own based on the memory of implementing this method previously. It turns out I wasn't as prepared to work through the code as I'd like. Revisiting the video tutorials I started to write down and analyze the code a little better. Working out the way that each design decision fed into another, I was able (with a little tweaking) to get my code running and bring up a simple grid of tiles.

The next step involved creating a "map" from pixels, where the colors represented tiles of different types that the program could read in and create the full map from. Using hexadecimal colors and a small (64px X 64px) "map", I was able to feed this into the level loader and move around the screen with the avatar. Lining my tables up was a second issue which meant I had to rethink and refactor my code to take the tables from an Array and build an Arraylist instead. Once the level loader read my map and encountered a "table" tile, it added a new Table instance to my ArrayList and set its x and y variables to match the tile.

Here the dark lines represent walls and the orange pixels are Tables

The next task will be to work on collision so that solid objects will be impassable. I will later add features for the sprites so that the level loader will determine if a table has adjacent tables and extending the length and capacity of the table accordingly. This will also involve some new sprites and logic to determine orientation, waiter interaction points etc. Once I get around to AI, I hope that the tile grid based system will work in my favor!

I imagine that in the final version of this program, the levels will be generated and packed before release rather than having the program read from the image files. Perhaps creating the initialized level and serializing it so that it can be read into memory, preventing tampering. If my final implementation also includes using a bitmap style mapping system, it may open up the door for creating my own modding tools or level editor, placing walls, computers, tables and other features that are checked by the program for compatibility against a set of game rules.

Larger level with Waiter star icon as placeholder. All tables occupied by debug mode options

Smaller level with pixel map overlay. Green pixel represents the Waiter starting position

Wednesday, 5 November 2014

Helping the binman out

Tonight ive been reading up on something that struck me while i was pondering the options I have for storing game data. If I create a new guest object at regular intervals, how do I make sure they arent sticking around, especially if I intend to simulate large numbers with any combination of ai activities.
Luckily there are some great summaries of the Java garbage collector that didnt get too science heavy for me. When a reference to a variable is lost, either through scope, reassignment or to lack of use, Java checks the programs memory for any variables or methods that may still have access to that memory address. Those suffering from abandonment are removed from memory by a low priority thread in the jvm. My problem was then, are my guests being deleted when they leave or were they living on. In order to figure it out I had to have my guest class increment a static counter each time its Constructor was called, and my Hostess class keep a tab on the number of guests at active tables. The first revelation found was that the hostess was creating groups even when the queue was full, and discarding them when they were rejected. While this wouldnt have been a huge memory problem, it was a simple fix to ensure the groupGenerator was not called unless the queue had room for more groups. After that I went about cutting ties to any groups that were done eating and had 'paid'. To do this I created a method in the Guest class to null any modified variables. This method was probably overkill! After any guests were gutted, the Group itself breaks ties with the Guest array, and the table breaks ties with the Group by disbanding. While any performance changes are probably negligible, it was good to think about the data being stored and how I want any large objects to kill their data before disconnecting from use in the game.
Today I also began sketching out a plan for the task system and how it could be implemented. Using tasks and a queue will allow me to break ai into much smaller chunks and simply list the steps needed to complete a task. It also allows me the future ability to add task transfer from one ai to another, effectively creating a means for waiters to really communicate and help each other out. I want to really have a good plan laid out before any of that system goes into the code though, id rather get the head scratching done before than during!

Monday, 3 November 2014

Working with the Hostess, queues and delta time

So ive got a small gym running for my program, a set of tables with placeholder art to show states and a non-viewable 'hostess' controller.
The hostess consists of a set of queues, which are offered a group of random guest size at random intervals. The hostess offers the group to a queue of matching description (those waiting for a table of 3 go into the queue for 3's and 4's) etc, using a best fit approach.
While the tables dont show any difference for max seating yet, eventually i will create different sprites for tables of various sizes and shapes.
Implementing the "arrival" of guests could lead to a more detailed look at the state of the performance, time of day and use of marketing strategies. Looking back at rct and its publicity options for gaining more guests, i may be able to add these kinds of features later on once the core gameplay is set.
At the moment the Hostess class is not intended to be a child of Staff, and is instead simply a controller of the flow of guests. If i later decide to have the option of a graphic representation, i would be able to give it a limited set of information and control to simulate human behaviour. (For instance, StaffHostess could have only limited view of the tables availability, and have to check around regularly to find which tables are taken.)
The Table class is currently maintaining itself by running update and incrementig a counter variable if the table isOccupied. Future implementations will take into account timed intervals for each state based on the guests and check against delta time for a change. (For instance, 4 guests will finish 2 shared meals quicker than 2 guests habing a meal each.)
My next step is to add StaffWaiter and a Computer to take orders and deliver Consumables to the table.

4/8 Tables Sat in various states