Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Environments #79

Open
4 of 45 tasks
1ForeverHD opened this issue Feb 19, 2021 · 1 comment
Open
4 of 45 tasks

Environments #79

1ForeverHD opened this issue Feb 19, 2021 · 1 comment

Comments

@1ForeverHD
Copy link
Member

1ForeverHD commented Feb 19, 2021

For those who stumble across this card and are wondering what an 'Environment' is: imagine a game where players have their own personal section of land. Within this local area, they can configure their own admin roles, settings, bans, etc which saves. Everything which takes place within this area though remains within this area. An area can be anything from a plot of land in a server, to a private server. This in essence is an 'environment'. The goal with Nanoblox is to allow the easy creation of these environments, while ensuring restrictions are in place to prevent abuse. By default, there is the 'Game/Global' environment, where changes impact every server (i.e. the default behaviour you'd expect of admin commands).




Ben's latest thoughts and proposals:

1. APIs should be simplified

  • For example, RoleService.createRole(isGlobal, properties) should just become RoleService.createRole(properties), where 'isGlobal' and 'environment' now become properties. Consider renaming 'isGlobal' to 'permanent'. These properties default to false and Game/Global.

2. Redesign how environments are defined

  • Instead of enums, consider strings, e.g. "Game" instead of main.enum.environment.Game
  • Considerations:
    • How and when are these environments created? For example, the Game is one entity, while a PrivateServer can have many different private server owners. Same for zone environments.
    • This should be responsible for creating the separate datastore entities too - every environment will own its own SystemStore key (instead of roles, bans, etc)
    • Also consider how a record may change datastore entities when its environment is changed - for this, remove the record then re-add it to the new environment
    • Restrict the changing of environments if it does not exist
    • An environment module with a function like .getEnvironment which returns a promise. If that environment has not been loaded before, then initiate it and continue afterwards.
    • Have a module where environments are created, then create the default environments:
      • Game
      • PrivateServer
      • ReservedServer - maybe combine this with reserved
    • Remove SettingService.createPrivateEnvironmentIfA

3. Every record needs to have a UID

  • For example, instead of bans["82347291"] it would be bans["82347291-IF9jL5UoJZ"] with a record property 'userId' that points to that user
  • This includes Settings, where instead of having settings["Player"] and settings["System"] it should be settings["Player-AbUkL5UoJZ"] with a record that contains the keys 'player' and 'system'

4. Every System Service needs to change

  • Every SystemService should have an associated object. RoleService would have 'Role', BanService would have 'Ban', etc. These objects will then contain the default values (instead of .generateRecord), the key 'record' (a State table where all display level values are stored), a default method :update(), which is the equivalent of doing .record:set(), and a a signal changed which mirrors .record.changed
  • When :destroy() is called on one of these objects, it truly erases the data
  • RoleService.recordAdded:Connect(function(roleUID, record) should become RoleService.roleAdded:Connect(function(role) and the same for roleRemoved, while roleChanged should be completely eliminated as the role object itself now has its own signal. Repeat for all other services
  • SystemService.getObject(UID) should always be the same, while services can have alternative getters such as RoleService.getRoleByName(name, environment), BanService.getBanByUserId(userId, environment), etc

5. Virtually everything should use 'pathways'

  • As the title says
  • Consider having 'changed' to achieve this (instead of descendantChangedSignal)

6. How system items are displayed

7. Belonging to multiple environments

  • Within Command verification, if a user performing an action where it's uncertain which environment to act upon (e.g. if a game owner goes into someone private server, and the private server owner gives them admin), a prompt should appear informing the user to select their preferred environment and then taking them to the Player Settings page to select this.
  • More details below

8. Objects/services now have to consider environments

  • Objects/services like bans will now have to account for environments when calling methods such as getHighestRole

9. Reconsider some of the challenges posed by the current System and ConfigService

  • This includes:
    • The retrieval of new config information every 10 seconds
    • The removal of items (such as roles) in game originally created in studio
    • The global updating of these roles

10. GDPR Compliance

  • When a user is wiped, make sure to wipe all their associated environments (reserved, private, etc) too



Currently Nanoblox has a 'global' environment where data can be saved (such as bans, roles, settings, etc).

Now consider how a similar environment can be setup for private servers and servers created through the SavePlaceAPI:
https://developer.roblox.com/en-us/api-reference/class/AssetService

Also consider how zone-based environments can be created. For example, a game where everyone has an assigned piece of land, and only admin commands can be used in that zone on players in that zone. The environment can be associated to a player, but can also persist after this player leaves.

This will enable private server owners for example to permanently ban people and create saveable roles within their own private place whilst no spilling out into the rest of the game universe.

Revamp System user.temp.descendantChanged

  • What happens if someone is banned on both Private and Global within surface level??????????????????????
  • Important Consider how getters will work? Do you have to specify the environment? If so, a lot of methods and places will have to be updated (e.g. Args getSystemSetting/getPlayerSetting). Also consider what happens to state tables like that from CommandService (e.g. 'lowerCaseNameAndAliasToCommandDictionary') and SettingService (e.g. 'lowerCaseColorNames')
  • Strongly consider reorganising surface level data (i.e. records) and events so that they have to be updated/set via a 'settingPathway' (e.g. "RoleSJDSFKLSDF.limitModifiers.global"), and then call ServiceName.objectChanged with the pathwayTable instead of settingName. Utilise createDesendantChanged (maybe) for this.
    • Rename 'pathwaySetting' to 'pathwayString' and then also have 'pathwayTable'. Make sure to do the same for the RoleService methods (which call it 'pathwaySetting')
    • Update the following services.recordChanged and give their objects 'get' and 'getOrSetup' methods which are mimiced from State
      • TaskService
      • RoleService
  • Where possible, try to merge TOP LAYER and OTHER LAYERS into one, neaten up
  • Completely revamp 'expiryTime' so instead of working for just the top layer, it can work for any layer (i.e. instead of doing record[key] = nil, do record:set(nil)
  • Finally finish off the color changer detector table within SettingService.loaded()

Other

  • Play around and compare SavePlaceAPI with Reserved Servers
  • Consider changing 'PrivateServer' Environment enum to just 'Private'
  • Reserved and Private servers have a unique game.PrivateServerId value, while CreatePlaceAsync Servers have a unique game.PlaceId value. Consider a way then to initialise a 'private' environment with just a normal PlaceId.
  • Consider an 'environment' enum for Roles. Items can include 'Global' and 'Private' (which includes Reserved Servers). This environment property then determines how all other actions behave too. For instance, if a player ('Private' environment as their dominant role) 'perm bans' someone, that person will only be banned from their private server, not the whole game (i.e. global).
  • Reconfigure System:
    • Consider revamping system user data so that it contains bans, roles, etc within a single user, instead of spread out over many, then whenever a private server is created, create a new system user
    • Create a SystemService with single method .createEnvironment(key)
    • Create an Environment object which contains the data loading/saving code
    • Move most of system handler code to Environment, while only keeping the 'Display' data which fires the surface level events and contains the surface level API
    • on :start(), have SystemService automatically create a 'Global' environment
    • check SettingService.createPrivateEnvironmentIfA, then create an additional environment with the game.PrivateServerId if...
      • privateServer is true and game.PrivateServerId and game.PrivateServerOwnerId > 0
      • OR reservedServer is true and game.PrivateServerId and game.PrivateServerOwnerId == 0
      • OR normalServer is true and game.PrivateServerId == nil
    • ensure this new setup works correctly with ConfigService
    • have ConfigService.setupComplete fire and set when Global data is finished, but don't worry about any additional environments
    • this means if a non-global environment is called (e.g. :createRecord()), that will fist have to check the environment exists, then yield if not loaded. ensure all APIs handle promises.
  • Introduce a third enum 'Multiple'. For all _isGlobal params within System objects (to be replaced with Environment), if 'Mulitple' is passed through, request the caller to specify. If caller player not present or no return within 10 seconds, default to 'PrivateServer'
  • Introduce an environment enum arg/param for System (e.g. :createRecord, etc), replace _global with isPermanent, and then update to all system services
  • Determine how roles can be hidden (for example, on a PrivateServer, you wont want to see Globals unless you're the game owner). Maybe split them into two categories for the UI (bans, roles, etc): 'Global' and 'Private Server'
  • Ensure Global Receivers and Senders also account for environment (for example, even if Global, if Private environment, only send to servers with the matching id)
@1ForeverHD 1ForeverHD changed the title Setup private server and private place environments alongside the global environment Environments Jul 31, 2021
@1ForeverHD
Copy link
Member Author

1ForeverHD commented Aug 19, 2021

To do for now

Brainstorm

  • The methods, property and design of:
    • How environments and systems interconnect
    • EnvironmentService
      • getEnvironment -- if does not exist, warn
      • getEnvironmentWhenLoaded -- returns promise which resolves when environment loaded all services
      • bindEnvironmentType(environmentType, action)
        • bind default ones:
          • global
          • privateServer
          • reservedServer
      • unbindEnvironmentType(environmentType)
      • canBroadcastGlobally - default false, if remains false ignore changes
    • Environment (object)

Mostly System / Environments

  • Create ban and unban command
  • See RoleService 'Role Order' and consolidate that: RoleService, Roles and Role Verification #102
  • Create objects
    • Have parent object called 'Record'
    • A property settings which is the record
    • Think how expirys will work, be hidden and eventually removed when the original player joins the server
    • Simply have a record:hasExpired(pathwayToTable) method and then check for this within BanService and LongtermService
    • Have record.changed point to record.settings.changed
    • record:update(settingsPathway, value) which handles the abstraction recordChanged does
    • ensure createRecord and removeRecord work properly (e.g. account for environment, return object, destroy object, nil from dictionary)
    • A method within services to associate properties (such as names, userids, environments, etc) to the object
      • Make sure to remain environment specific!!
      • System:getRecordsWithSettings(...)
      • System:getRecordsWithSetting(pathway, environment) - if first time, sets up a records descendant changed signal and association table
      • getRecordWithSetting - same as above but results[1]
      • Make sure it functions like current TaskService setup
      • Convert TaskService to this new method
    • All service method APIs should have an end environment paramter. If nil, this will default to the global environment object
      • Change environment key to environmentUID
      • Setup an environment service and module
        • Environment.getUIDFromType()
        • bind and unbind methods which determines how UIDFromType works
        • CONSIDER HOW NON-GLOBAL ENVIRONMENTTYPE ROLES WORK (e.g. PrivateService, ReservedServer, etc)
          • We still want them to remain on the Global environment, but to create different environments when criteria is met
          • It's also important that when a role has the global UID but a non-global Type then it gets disabled for that server. Consider an 'active' property for roles that when set to false then wipes it from the user role information records
          • ensure change differences within studio/config then apply ingame for all environments
        • completely setup config (see more details below)
        • use getUIDFromType within config and have the environmentUID set before being added into the temp/perm records
      • Introduce a method/signal where you can listen for environments loaded, then in framework, wait for Global environment to load before completing initialisation
      • Introduce a job.environment which is passed down from CommandService verification
  • Setup Record System objects:
    • Ban
    • Command
    • Job
    • Longterm
    • Role
    • Setting
    • Warn
  • For the following services...
    • Update their events/signals
    • Update all methods to include environments (and to remove isPerm/Global)
    • Sevices:
      • BanService
      • CommandService
      • JobService
      • LongtermService
      • RoleService
      • SettingService
      • WarnService

Additional

  • Ensure methods like Args getSystemSetting/getPlayerSetting) are fully updated with environments
  • Update state tables such as the following so that they work for multiple environment, instead of single initialisation
    • CommandService 'lowerCaseNameAndAliasToCommandDictionary') -- IGNORE THIS, ITS ACTUALLY FINE
    • SettingService (e.g. 'lowerCaseColorNames')
    • Revamp all record:getTable and setTable
    • TaskService everything
  • THINK ABOUT THIS: Everything related to Framework.loaded needs to be revamped
    • This method needs to entirely disappear
    • Maybe an environmentLoaded alternative which can be listened for?
    • What happens about framework:waitUntilLoaded? Should this wait be removed entirely, but then how do you ensure an environment is loaded when you wish to retrieve information about it? Maybe a wait until specific environment loaded event/method instead?
    • For example, what happens about BanService.playerLoadedMethod if this is called before the environment loaded?
  • Config
    • Update all config (bans, roles, etc) with EnvironmentType
    • When config is loaded in game, sort based upon its EnvironmentType
  • Setup an 'Individual' EnvironmentType Enum (and replace with Other)

Test

  • Expiry on different layers of records work (and state:add())
  • Changing a records environmentType and environmentUID
  • The creating and saving of records, such as bans, in non global environments like private servers
  • The changing of default information within config/studio after already creating and changing things within a non global env

Networking

  • User information which determines if they have the main menu open/closed
  • User information to determine which pages/info they can access
  • A remote event fired to server to initially retrieve information and inform server menu is open/closed
  • The remote event listened on client to handle system/record data changes
  • Make sure to filter out tables which have an expired expiryTime
  • Have system/record deduce who needs updating and can access information, and fire off accordingly

Data Caps

  • Explore DataStore limits. Do new datastores need to be created per system instead of keys?
  • Consider creating an arg called 'recordString'. It behaves the same as a normal string but gets capped to around 200 characters
  • A Cap on the total number of record types (bans, roles, etc)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant