Skip to Content
 

Desiging games for databases

8 replies [Last post]
larienna
larienna's picture
Offline
Joined: 07/28/2008

I almost finished my stock ticker game, still have some issues to deal with. The game is powered by an sql database. During the process, I did hit some walls in the design, which makes the limits visible now. Doing simple things like shuffling cards or player order can be a complete mess if done strictly in SQL. The advantage to do it strictly in SQL, it that the "rules" can be in a script and tested without even running the game making debugging easier. Individual queries can be tested too and the game becomes moddable. The "Put the rules in a script" was not originally anticipated, it became a useful emergent behavior.

That means that the way to design games has to be different if I want sql script friendly games. So the game design needs to be adapted to fir the new medium. I had a discussion with chat GPT about how to change my mindset during game design to make sure it is SQL friendly. I asked to use Twilight imperium and PTO 2 (which can be converted as a space opera) as example of mechanics that would fit well or not into an sqlscript only game. We roughly came up with the following guidelines:

1. Focus on state transition instead of series of steps(procedures) with decisions at each step.
2. Avoid ordering stuff, or manipulating the order of stuff (ex: deck of cards). Simultaneous actions is preferred to sequenced turn order.
3. Avoid Heterogeneous Collections (ex: mixing cards of different cards in the same deck)
4. Bulk transaction at once. Resolve all actions at once instead of individually.
5. Avoid pools of tokens or resources, replace with only a resource value (1 variable)
6. Deterministic resolution is better than random resolution.
7. Automated resolution (combat) is better than having choice at every steps
8. Avoid any interruption of opponent's actions (take that cards) or interactions.

When you look at those rules, it seems to make Play by Mail or Play by Web games fits more the criteria. In those kind of games, all players submit their order, and they are all resolved at the same time at the end of the turn.

Now the most complex part is how to design games under those rules that are strategically interesting. The AI came up with a golden rule:

"Interesting choices come from constraints + uncertainty, not from execution complexity."

It Identified 5 design patterns which are database friendly:

1. Overcommitment / Allocation: Player must divide limited resources. Pure SQL. Deep strategy.
2. Simultaneous Bluffing: Players commit without knowing other player's data. Emergent gameplay. No procedural complexity
3. Threshold Effects: Outcomes depend on totals that triggers effects. If sum > 10, trigger effect. Clean. Scales well.
4. Positional Advantage: (using Precomputed adjacency) area of control, Choke points, connection. No pathfinding needed during play. Strategy emerges from graph structure.
5. Delayed Payoffs: Actions resolve later. Encourages planning. Works well with logged orders.

So I'll have to rewire my brain and see how some of the ideas I have in my lists could fit this paradigm. There are ways to bend those rules, but that means it requires coding it differently. Like if I want tactical battles, I need interaction, so I cannot do the entire combat resolution automatically in an sqlscript.

questccg
questccg's picture
Offline
Joined: 04/16/2011
I've never heard of ANYONE using SQL to make a GAME!

Usually from my days you had an APPLICATION in C++ or Turbo Pascal that was responsible for the GUI and handling "interaction" with a Database VIA SQL Statements. I have never seen some write ONE SQL Script to handle all the different phases of a game. What you are doing is @larienna special coding.

Getting back to normal... You either have a DEV KIT like C# or Java or some kind of platform like Unreal or Unity (for 3D Games) that allows you to build the INTERFACE or the ENVIRONMENT (like for 3D) and you code scripts that run from the PLATFORM... Not an SQL Application.

I don't think I've EVER heard ANYWHERE where one SQL Script manages the Game in it's entirety without the need of additional logic.

And normally the TRANSACTION are managed by the "Platform" or piece of software that you are coding.

So if it's WEB APPLICATION that's coded in PHP or RUBY or PYTHON (as examples). And then the APPLICATION makes SQL calls for insertions and can call multiple scripts (smaller ones) and then the APPLICATION gets back control and COMMITS the transaction.

I've been doing Systems Integration for 10+ years in the past... And we always used our platform (WEBMETHODS) to interact with SQL Databases via SQL. But we had WEBSERVICES some API-RELATED and published, some private of internal logic, etc. etc.

But never have I seen ONE GIANT SQL Script handle the entire GAME LOGIC. That is super-weird... And I don't care if AI helped create it... That's not how most APPLICATIONS (WEB or PC Software) are programmed when they interact with a DATABASE.

The Database doesn't have any LOGIC... It's the APPLICATION that has all of the logic related to what it does and needs to ADD or REFRESH (Insert or Update) to the tables in the database.

Like I said, when I saw the script I saw it doing NON GENERIC instruction which are NOT part of SQL unless given a specific type of database being used.

If you had to ASK AI to help you with the SQL specifics... That shows me that how you were doing it is NON-STANDARD. SQL is simple: SELECT, INSERT, UPDATE and DELETE instructions. Those are the STANDARD SQL operations and should cover the entirety of what you need to know to code SQL for handling ANY SQL database. Not db-specific code.

Anyhow... I'll look again at that BIG script again... If I can find it in the discussions.

Bottom line: what you are doing is NON-STANDARD. And AI invented it's own script to handle what your application should be using to handle transaction and DB-LOGIC from your application.

Note #1: I tried to search BGDF.com for your SQL script ... But I couldn't manage to find it. I checked my Private Messages too (PMs) and neither there. But I know you shared it with me... I just can't find bloody hell where it is...?

I'd like to review it again to point out any NON-STANDARD SQL used in it... But I could not find the THREAD on the forum...???

larienna
larienna's picture
Offline
Joined: 07/28/2008
I am getting close to

I am getting close to finishing the implementation. I plugged in the AI and it plays the game pretty well, it defeats me all the time so far. I need to fix some details am implement the automated build and deployment process which will be a pain.

SQL script do have a logic, but a logic of its own. "Iterate over all records in a table" = easy. "Iterate only 3 times" = hard. So it is not super intuitive.

Now the SQL script is a side effect I did not expect when I designed my library. Of course I do some SQL command inside the C code, but it is much more annoying to manage, especially when reading data from the database. I need custom utility functions, or use my GUI that query the information for me. Else I need to call a function for each column to read in a record, not convenient.

Adding game logs using triggers is another side effect that works pretty well that I did not expect when I started making my library.

So if the queries could be only put in a file, that is way more convenient. It's also testable from the command line without even running the game. I can make a bash script that creates a new game and insert test data without opening the game. I could even make automated test using this method.

So If I could find a game format that can keep the rules in scripts, that will be fine with me. I will make the sacrifices listed in the first post to be easier to implement and maintain as scripts.

If you want more "classic" scripts: here are the new game scripts that create tables and insert data:

https://gitlab.com/larienna/stockticker/-/blob/dev/sql/newgame_create.sq...

https://gitlab.com/larienna/stockticker/-/blob/dev/sql/newgame_insert.sq...

Else there is the famous end of turn script that implements the core rules.

https://gitlab.com/larienna/stockticker/-/blob/dev/sql/endofturn.sql?ref...

I just insert the dice rolls into the database, and launch the script. Easy. Think of it as state transition. This is the list of steps that the game rules force a transition from one state to another.

questccg
questccg's picture
Offline
Joined: 04/16/2011
I don't understand...

larienna wrote:
I am getting close to finishing the implementation. I plugged in the AI and it plays the game pretty well, it defeats me all the time so far...

How can the AI beat you every time? I mean you programmed in the LOGIC to the game... So you should understand what the AI is doing and do that or BETTER?!

Also ... The AI beating you every time ... Is that good from a REAL player's POV??? I mean, the AI should be competitive but NOT WIN "every time"... Know what I am saying?!

It's one thing to have an AI that is challenging versus as AI that is "broken" and wins ALL THE TIME. Sounds to me like you need to re-think the AI and make sure that it is competitive but "beatable". And NOT "win every single time"!

I think your AI is too GOOD at the game. You need to make it less efficient at playing the game such that the game can be WON by the players. There is no point in having an AI that can't lose (know what I mean...)???

And furthermore as the Game's Designer... You should know the OPTIMAL method by which to play and you should ALWAYS (well maybe the AI can beat you some times...) win knowing the logic of the best possible method of play.

I'm just saying that "Winning every time and beating the creator of the game" is well... Not good IMHO. Maybe if you have AI difficulties (Easy, Medium and Hard) you could be 1/3rd the way done with the HARD AI working, know you need to figure out what are the EASY and MEDIUM AIs...

Cheers @larienna and keep up the good work!

questccg
questccg's picture
Offline
Joined: 04/16/2011
It's not impossible. Could be complicated depending on your SQL

larienna wrote:
...SQL script do have a logic, but a logic of its own. "Iterate over all records in a table" = easy. "Iterate only 3 times" = hard. So it is not super intuitive...

That's not true. You simply need another COLUMN per turn which is a VALUE. At the start of "Each turn" you reset the value to "Iteration records"... So in your case you UPDATE the COLUMN to "3".

Next in your SQL that iterates over ALL the records make a check to see IF the value is greater than "0" and if it is... Do the iteration. ONCE DONE, Update the value to "Value - 1" if it is greater than "0".

This will then allow you to Iterate a specific amount of times.

Obviously the issue is HOW the SQLs are built and when you have control to UPDATE the value.

***

What I was a bit UNSURE of was "Iterate over ALL records" versus "Iterate over ONLY 3 records"... Or was it "Iterate over ALL records 3 times"... Not sure which one it was. Because you were not 100% clear in the explanation.

***

Anyways you could do something similar... In either case.

And IF you have to go over only "3" records... You could have a COLUMN "isSelectable" BOOLEAN and prior to SELECTING you do a RANDOM UPDATE setting the "isSelectable" Column to "1" and just SELECT the columns with a "1". Once done, CLEAR by running an UPDATE to make all "isSelectable" Columns to "0"...

Something like that.

Again I'm not 100% sure of your CASE... But it is DOABLE.

Cheers!

questccg
questccg's picture
Offline
Joined: 04/16/2011
I don't know HOW(?) your AI works ,,, But IF

The idea of how the AI works is due to how many STOCK records it can compare and you want to LIMIT the amount of records per TURN, you can use the "IsSelectable" method that I presented in my previous comment.

So IF the idea is to LIMIT the amount of STOCKS the AI can "review" prior to making its purchases ... Limiting it's scope could allow you to make a DEGREE of "knowledge" for your AI. Meaning 90% is HARD AI, MEDIUM is 75% of the records and 50% is EASY.

I'm not sure how(?) your AI works... However if this is the reason BEHIND the SQL question ... Well restricting the AI's visibility means it ONLY selects the OPTIMAL stock in a subset of records. So sometimes it doesn't find the BEST stock to buy because it is NOT a part of the "subset" and therefore OUT-OF-SCOPE for the AI during that TURN.

Again this is just me SPECULATING (Haha!) ... But could be a rational for having such an SQL dilemma in the first place.

Wishing you all the best.

questccg
questccg's picture
Offline
Joined: 04/16/2011
And if I am correct about your AI ... Well then

Having it go through 100% of the Stocks every TURN means it ALWAYS selects the BEST Stocks to buy. And like you say, it beats YOU every time.

Throttling that with 90%, 75% and 50% record visibility (It may be a bit more complicated than that) will give you a more balanced AI. Remember there are two (2) schools of thought when it comes to the VISIBILITY:

#1> Always ensure that 90% x Record Count is flagged as SELECTABLE.

#2> Allow duplicates which may mean LESS than 90% records are SELECTABLE.

These are two (2) options. Obviously #1 is a bit more complicated because if you select a RECORD which is ALREADY "Selectable", you need to TRY AGAIN. And this could happen for more than one (1) record in one randomized selection.

The second option is easier to implement and doesn't WORRY about duplicates. It just means that AT MOST 90%, 75% or 50% of the records are SELECTABLE. But it also means that the count can be LESS than those "targets".

This second option makes the AI more "fluid" in that it's not PERFECT when it comes to selecting it's subset of records.

Anyways these are the two (2) options available to you... If this method of SELECTING is relevant and makes sense for the AI in your game.

Cheers!

larienna
larienna's picture
Offline
Joined: 07/28/2008
The AI is basically an stock

The AI is basically an stock evaluation function that determines the weight and randomness is weighted according to this value using normalization.

Roughly the steps
1: Select 3 stocks randomly using the stock sell weight
2: For each stock (slice of 500) in selected 3: SELL or HOLD: Normalized probability between the sell weight and the hold weight.
3: Zero out the buy probabilities of stocks where at least one was sold.
4: While there is enough money , use a weighted random roll based on the buy weight to determine the stock to buy.

Now AI have different personalities, a random selection of parameters (ex: average, standard deviation, hold weight, etc), which could make certain AI stronger than others. I did not make a simulation of which AI parameter is the best and rank them by strength.

Claude and ChatGPT recommended that the way the AI works could be the subject of a you tube video I can make. So I guess, I could just do that.

The situation when I needed 3 occurrence is to insert 3 rolls in the roll table. But the amount of rolls is dependent on the game.nb_rolls field. ChatGPT kind of made complex union work around in a CTE to be able to generate 3 instances to loop over. Very complex and non-intuitive.

Same thing with giving each player a unique card, that is complicated. I can give many players the same random card. Else I need 2 CTE query, bind them together and make the assignment. Its another tentacular query. This is how I call them. Not intuitive at all.

This is why I am aiming for a new set of rules for a new game medium.

larienna
larienna's picture
Offline
Joined: 07/28/2008
If you want a detailed

If you want a detailed explanation of a simple update query, here is one:

UPDATE stock SET current_price = current_price + COALESCE( ( SELECT SUM(move * number) FROM roll WHERE roll.fk_stock = stock.pk ), 0 );

This query changes the value of the stock on the stock market. For each of the stocks in the stock table, it updates the current_price using the information in the roll table. It takes move which can be either -1, 0 or 1, and determines DOWN, DIVIDEND, UP. While the number can be 5, 10 or 20. It multiplies move by number to make movement go like +10 or -20. Then sum it up so that an GOLD UP 20 and GOLD DOWN 20 could cancel each other. COALESCE is used in case a NULL is returned, for example when no rolls matches the stock to update. It makes sure the price does not get multiplied by NULL, which would set current_price to NULL.

Syndicate content


forum | by Dr. Radut