Giter VIP home page Giter VIP logo

gamemode's Introduction

Trade Wars

Trade Wars is a free-roam, item-collection and combat oriented SA:MP gamemode.

The primary objective of the game is to make money. The world contains randomly spawned items at over 8,000 locations, some harder to find than others. These items range from common household junk to rare and unique trinkets. A network of vendors across the world will pay good money for quality items. Prices will fluctuate, driven by a simulated economy.

If prices are pretty low for your Green Tinted, Engraved, 7.62mm AK-47 then you can trade it with another player for another item you might make a quick profit off. It would suck if the price of that AK-47 shot up the next day...

This gamemode aims to bring together the economic aspects of Roleplay and the item hoarding of Scavenge and Survive with a side order of free-roam, light RP and fun.

Usage

Get the Code

First get the repository and dependencies, either with package get:

# Recommended: run this inside a directory named TradeWars
sampctl package get TradeWars/gamemode

This will clone the project to your current directory if it's empty or it will create a new directory named gamemode and clone there. After this, all dependencies will be pulled and the source code will be ready to build.

Or you can use git clone:

git clone https://github.com/TradeWars/gamemode.git
cd gamemode
sampctl package ensure

This doesn't download the dependencies so you must run package ensure after cloning.

Build The Package

Once you have the code, make sure your terminal/editor is open to the project directory then run a first build to make sure everything is working:

sampctl package build

The master branch should never have errors but may include warnings from time to time.

Set Up Storage

This project uses a custom backend for storing data. That project is available here and you can simply download one of the release binaries and run it.

By default, when you run the ssc executable, it will launch in "temporary mode" which is a no-configuration setup and is instantly listening for connections and will store data in-memory with no database. This allows you to get up and running very quickly.

The default listen address is :7788 so you should be able to access http://localhost:7788 via curl with the header Authorization: cunning_fox which is the default temporary auth string.

Run The Package

Now you can run the server with sampctl package run and connect to it via the SA:MP client. When you connect for the first time, the game server will submit a HTTP GET request to http://localhost:7788/store/playerGet?name=<your username> which you should see on the ssc process log. If all goes well, you should see two messages: one to acknowledge the request and another that logs the response data.

Debug Logging

Throughout the code, there are debug logs that use Southclaws/samp-logger's dbg function. Different modules and packages have named debuggers which you can enable by adding an entry to the debug entry in settings.ini. For example, if you wanted to activate player and weapon debug logs, you would write:

debug/0=player
debug/1=weapon

Contributing

Please see the contributing guidelines if you are interested in contributing to this project. If you are interested in contributing regularly, contact me on Discord and I will give you push access to the repository.

gamemode's People

Contributors

southclaws avatar thecodeah avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

orsx

gamemode's Issues

In-Game Development Tools

During development, there needs to be tools that allow easy navigation, spawning things, changing variables and configuring the game on the fly.

  • Teleport to position
  • Spawn Vehicle
  • Spawn Item
  • Fly/Airbreak

Dynamic Worldgen

Mentioned briefly in #5, the concept of periodic server restarts should not exist in this project. From the start, I want to build in dynamic world generation that periodically replaces used up resources over time dynamically instead of relying on a full server reboot to spawn new items, vehicles, etc.

This will mainly be an ongoing effort while new things are added but initially the focus is on:

  • Vehicles
  • Items

Vehicles

Vehicles is waiting on ScavengeSurvive/vehicles to be completed.

For now, simple vehicle spawns should be fine.

Organise Repository

The repo needs some housework in regards to issue labels and standardised naming conventions.

I've settled on [Prefix] for issue names, now to organise labels to reflect these so the prefixes aren't necessary.

This is based off of Scavenge and Survive and Yashas' work on the Pawn compiler repository labels.

Should probably use this: https://github.com/jhare/github-label-copy

Labels can be in a few formats:

  • type: subtype
  • type:subtype
  • Type: Subtype
  • Type:Subtype
  • [type] subtype
  • type/subtype
  • Type/Subtype

Not sure which is easier to read yet...

area (blue)

  • meta - issues regarding issues themselves and GitHub in general
  • repo - repository layout, dot files, etc
  • build - the sampctl build and ensure process, dependencies, etc
  • code - an actual source code problem, bug, regression, etc
  • gameplay - a problem with a gameplay mechanic that isn't related to code bugs

status (yellow)

  • confirmed - the bug has been confirmed
  • deferred - put off until a later time or depends on something else being solved first
  • in-progress - actively being worked on
  • duplicate - duplicate of another issue
  • invalid - doesn't warrant an issue at all
  • cannot reproduce - the bug cannot be repeated by developers, possibly user error
  • discuss - requires discussion before further action

type (green)

  • question - a question regarding the area the issue is about
  • suggestion - a high-level suggestion for an idea, little to no implementation details or roadmap
  • proposal - a formal proposal for a new feature or change to a feature that includes implementation details
  • bug - unexpected behaviour caused by mistake in code
  • regression - bug caused by upstream changes
  • optimization - an improvement that relates to performance of the code at runtime

severity - these apply only to type: bug issues

  • class-A - (black) a run time error that crashes the server or causes memory corruption
  • class-B - (red) significantly impairs its basic functionality or prevents feature access/use
  • class-C - (orange) purely visual or gameplay related annoyance, does not impair functionality

others (grey/teal/neutral colour)

  • good first issue - good for a new contributor
  • help wanted - help wanted from another contributor

pull requests:

  • work in progress - pull request should not be merged
  • needs test - requires testing
  • needs docs - requires documentation
  • needs discussion - requires discussion before further action
  • needs review - requires another contributor to review

Player Grouping

Players should be able to create groups.

Not sure how this will work, Marcel had some nice ideas regarding using items to signify this, like a Radio that you would share with others for communication.

Items

Item types should be pulled over from SS.

Items should spawn on the map, same as SS, may as well re-use that code.

In addition to this, I'd like to add in-world containers that spawn items - dumpsters, boxes, etc. These should be static in the world and not allow placing items back inside.

  • Items
  • Item Spawning
  • Loot Tables
  • Loot Sources

High Level Architecture Design

This thread documents and discusses the high-level design of the overall architecture of services that surround the gamemode.

In development, we will make best efforts to make it easy to spin up the game server alone without needing to connect to anything else unless you are specifically working on features that require these external services.

For example, building the codebase with the NO_AUTH constant will disable authentication and thus, won't require running SSC in the background to perform login and registration.


Services

Below is a concrete list of all proposed services and their purposes.

SSC - "ScavengeSurviveCore" - or "StorageServiCe" (🤔)

  • Author: Southclaws
  • Language: Golang
  • Status: Built and stable

A JSON-based storage server backed by MongoDB built for storing player accounts and administrative data such as staff roles, reports and bans.

This was originally built for Scavenge and Survive - hence the name - but was repurposed to be a generic account storage service.

It provides an API via HTTP which provides RPC endpoints for CRUD operations on:

  • player accounts
  • bans
  • admin status
  • player reports

Timerunner

  • Author: Southclaws (?)
  • Language: Rust (?)
  • Status: Being designed/experimented with

This is an event store for receiving events from other services and storing them to a Timescale database (a time-series PostgreSQL database).

Events will play a key role in both administrative, statistics and possibly even data operations. An event will be any player action on the server (and maybe some non-player actions). This can involve:

  • bullets fired - along with their position, vector, target entity, etc
  • vehicles entered - along with their unique ID, seat, position, etc
  • items picked up - along with type, item position, player position, etc

Not only will this be extremely useful for anti-cheat (based on years of experience dealing with the creative cheaters in Scavenge and Survive) it will also serve as a complete history of everything that happened on the server in chronological order, easy to query.

More neat applications of this data include:

  • generating fun statistics and graphs, like "Southclaws shot the most bullets in January" or "Alice entered an average of 1.5 vehicles per hour"
  • seeing which features get used the most and the least - this is very useful information because this is an open source side project, we all have lives/jobs/education/etc so we have limited time - using this information to better focus our efforts will be a big help
  • debugging, log files can be useful for tracebacks and errors but often, you need a near full reconstruction of things that happened - using this time-series data, reproducing bugs can be easier because almost everything is recorded. This means entire gunfights or chases could be (sort of) re-played using proxy objects in the game engine, which can help with figuring out which series of actions caused a bug.

Econ (economy? vendors? not sure yet)

  • Author: Marcel, maybe Southclaws?
  • Language: Kotlin, maybe something else
  • Status: Being discussed and designed

This will serve as the "brain" for vendors (#3) to control the simulated economy. Vendors will buy items from players but vendors also have their own finite amount of money because they are individuals. So some omnipotent deity (nicknamed "Gaĩa") with infinite money needs to exist to purchase these items from vendors at market price.

Because this stuff is complex, it was decided that it would make sense to pull this entire piece of functionality out to a separate service. This also means the vendor's data can be queried by other services, like maybe a web frontend that lists vendor item prices.

This thing should be kinda simple, there won't be a whole lot of "artificial intelligence" on the trade-making side of things since actual trades will be done by players.

There also won't be an order book or ledger (the event store will serve as a ledger) - trades are not negotiated, whether that's between players and vendors or vendors and Gaĩa. There is one set market price. Though this could change, a full scale player-to-player trading platform would be very interesting to build.

Diagram

Here's a rough diagram that I drew at 11pm one night that outlines the communication channels between these services.

  • "GS" is the Game Server
  • Events is the "Timerunner" service
  • The game server > timerunner may not use Redis and may just use HTTP

image

Storage via an API

Currently, data from the gamemode is stored via an external application called SSC or "ScavengeSurviveCore". That project can be found here

There are a number of reasons for this:

Language

Pawn isn't the nicest language. In my opinion, it's best to avoid using it for anything other than interacting directly with the SA:MP API for scripting gameplay mechanics.

Building queries, serialising data, working with trees, arrays, objects and hashmaps isn't a nice experience at all. It's messy, requires lots of overhead for conversions and it isn't type safe, only tag safe.

Building the storage layer in a language such as Go allows for all of those problems to be solved.

Separation

Separating the storage layer to another application allows it to be individually unit-tested. It also provides a boundary via an API which can be easily documented automatically using the data inside the application.

This also means the database internals can be tweaked and updated without bringing down the main server. As long as the API contracts are intact, all services communicating with the database remain online. These internals may be things such as optimisations, changes to the internal data structure or additional endpoints and features.

MongoDB

Another reason for choosing this path was being able to use any database, not just MySQL - and not just relational databases. Because this project will evolve fast, with new pieces of data being added to players with each new feature, keeping track of a schema and making sure it's updated can be a hassle.

Another reason for MongoDB is the ability to use tree structures for nesting data such as complex objects and arrays. This can be much simpler than dealing with one-to-many relationship tables with the relational model - depending on the use-cases of course. MongoDB does have a powerful aggregation toolset for performing the same operations as JOINs.

Assuming MySQL plugin usage: In development this would involve spinning up a new database with the new schema each time, which isn't much of a problem but in production, performing an alter table requires bringing down the game server in order to perform the update on the live data, running tests to ensure it's fine then bringing up the game server again.

With the separation model, if MongoDB doesn't work out, it can easily be switched out with no necessary changes to Pawn code. The database could be swapped out for Postgres or MySQL before launch if necessary.

External Access

(By external I mean other applications within the same network, not public access)

In future, other web services may want to interact with this data (a statistics page or a user control panel for example). The web uses JSON already and since the SSC API provides data as JSON, building a UCP or statistics page or any kind of frontend would be extremely simple given the data is readily available to consume and display. Using a database without an API would require writing a backend that directly talks to the database, queries the data then processes it in order to turn it into JSON data for being used on the frontend.

Summary

So this is why the service model + MongoDB was chosen for this project. Yes it's new, yes it may be confusing at first. However, I believe with good documentation and well designed boundaries and APIs, this model is far superior to the traditional SA:MP approach of baking database interactions into Pawn code.

Hopefully this covers everything, ask questions below and I'll answer anything that isn't already here.

Poke holes in this concept and criticise it as much as you can!

Territories

The game world should have some version of "gang zones" or "regions" or "territories".

I'm not totally sure how this would work yet. Maybe different zones could give players bonuses or raise the amount of items spawning in that region.

Below is a map (#8) of region data which could be used for either territories or territories could be sub-areas of these.

unknown

Here is that region map overlaid on the satellite map with region names too (download to see the names)

gtasa-blank-1 0-ss-map

Vendors and Item Economy

Vendors are actor-run shops around the map that provide item trading facilities for players.

There will be Vendor Types which describe high-level information about a vendor such as a name, a skin and a set of item types along with price ranges that the vendor will sell for.

Then there will be individual Vendors which have a world position and a vendor type. Vendors will stock up on goods randomly and the amount of items and price will be dependent on some attribute assigned to the item.

Trading

Players should be able to trade items via an interface.

This could make use of textdraws and dialogs. There may be some useful UI libraries available to make this easier.

Define ItemType Weapons

Once item types are in, pull in the weapons package and declare a bunch of weapon types.

Then some loot can be spawned and at least the gamemode is at least slightly fun for the time being.

Repository Standards

In this thread I'm proposing some standards for things like commit messages and change logs etc.

First, Changelog format:

https://keepachangelog.com/en/1.0.0/

This may be necessary for when the server is public, git commit messages are not useful to players.

The next is a commit format:

https://gitcop.com/features

I originally hated this when I attempted to contribute to a repo and my commit message was 80 characters long and they wanted 79. I also didn't start it with the correct word.

However there are some useful features in this tool. It may help to force contributors to make commit messages easier to read however I wouldn't enforce it really strongly, just on regular contributors and team members.

Safezones

Safezones are locations in the world that are combat-free which allow players to chill out, RP and not worry about being attacked.

This should make use of an event emitted from ScavengeSurvive/health which should prevent wounds from being inflicted.

There should be some smooth transition from holding a weapon to holstered too. I'm not sure how to handled this one yet.

Automated Deployment Strategy

This may require some sampctl work but I'd prefer not to at the moment.

Pushes to master branch should trigger a webhook. The webhook should trigger a rebuild of the package and redeployment. I'm still working on sorting out exactly how it's going to be hosted (most likely, Docker).

Load spawn points from a file

Map edits will be private so spawn points should also be as spawns may be located inside map edits.

Spawn points can either be JSON or INI, doesn't matter.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.