Skip to content

Commit

Permalink
feat: mudwar prototype (nyc sprint 2) (latticexyz#59)
Browse files Browse the repository at this point in the history
* refactor(ri): use int32 instead of uint32 in all components

feat(ri): combat MVP (latticexyz#58)

fix: use int32 everywhere

fix(ri): do not heal defenders when attacking with negative hp (lol)

fix(ri): fail stamina reduction if not enough is present

feat(ri): death MVP (latticexyz#61)

Blueprints (latticexyz#64)

* feat(ri): prototype MVP

* fix(ri): set current stamina to 0 when spawning a soldier

* refactor(ri): prototype -> blueprint

feat(ri): adding path movement, moveSpeed and aStar pathfinding, remo… (latticexyz#62)

* feat(ri): adding path movement, moveSpeed and aStar pathfinding, removed keyboard movement

* fix(ri): delete destination system, use position system for local path logic

* feat(ri): change MoveSpeed from uint32 to int32

* fix(ri): delete old TODO commend

* refactor(ri): remove timestamps from right click stream

* fix(ri): filter right click stream correctly, remove unecessary checks in path viz

* refactor(ri): clean up rightclick stream

BlueprintComponents (latticexyz#66)

* feat(ri/contracts): add BlueprintComponentsComponent to allow dynamic construction of blueprints

* fix(ri): fix BlueprintComponents getEntitiesWithValue

feat: merge main to get new systems pattern (latticexyz#69)

* feat: merge main to get new systems pattern

* refactor: move PrototypeSystem back to LibPrototype

* feat: new forge test infrastructure

* fix(ri/contracts): fix stamina update to allow stamina to go to 0

* fix(ri/contracts): allow combat between attackers with no health or defenders with no attack

* fix(ri-contracts): fix dev dependencies and increase local gas limit

* feat: use dev mode to disable cache in sync worker

* fix(ri/client): pass devMode param to createSystemExecutors

* fix(ri-contracts): use existing variable

Co-authored-by: Andy Cernera <kooshaba@gmail.com>

Co-authored-by: Andy Cernera <kooshaba@gmail.com>
Co-authored-by: Big Nuge <davidkolop@gmail.com>

* feat: add FactorySystem for constructing units (latticexyz#72)

* Capture entities (latticexyz#73)

* fix: remove LocalPosition when Position is wiped

* fix: give all component write access to CombatSystem

* feat: capturable units transfer ownership to attacker instead of dying in combat

* fix: properly restrict CombatSystem component write access

* feat: spawn points (latticexyz#74)

* feat: spawn points

* refactor: spawnable -> spawnpoint

* fix: comment

* fix: various fixes (hot reload, getComponentValue) (latticexyz#76)

* chore: remove constant fallbacks for network config

* fix(recs): do not early return for partial undefined values

* fix: hot reload issues

* fix(recs): return undefined if non-optional type is undefined

* fix: typo

Co-authored-by: Big Nuge <davidkolop@gmail.com>

Co-authored-by: Big Nuge <davidkolop@gmail.com>

* feat: inventory (latticexyz#75)

* feat(ri): adding inventory, gold, and prototypes from prototypes

* fix(ri-contracts): fix write access to position and stam comps and add owner check

* refactor(ri-contracts): remove debugging lines

* fix(ri-contracts): fix gold not appearing as an imp and leaving plain tile

* refactor(ri/contracts): generate entity IDs inside of copyPrototype function

* fix(ri-contracts): add client distance check for takeItem, fix prototype calls in init

* feat(ri/client): simple inventory ui

* feat(ri): add inventory library, transfer, burn and spawn item, and drop item on death

* fix(ri-contracts): fix combatsystem deploy write access for new inventory drop

Co-authored-by: Andy Cernera <kooshaba@gmail.com>

* fix(network): tx queue nonce management (latticexyz#77)

* feat(ri-client): wang tiles (latticexyz#78)

* feat: wang works

* fix: changes to work with nyc-sprint-2

* fix: remove autogenerated art files

* fix: remove blueprint reference

* feat(art): adding art from git@github.com:latticexyz/ember-art.git

* fix(ri/contracts): remove unused types

* chore(phaserx): removed unused getTileAt

* fix: review

* fix: scripting with systems

Co-authored-by: alvrs <alvarius@lattice.xyz>

* feat(ri/contracts): factory system properly spends resources (latticexyz#79)

* feat(ri/contracts): factory system properly spends gold during construction

* refactor(ri/contracts): use getEntitiesWithValue in LibInventory.getItems helper

* fix(ri/contracts): spend the proper amount of resources when building in factory

* fix(ri/contracts): fix reverts in getInventory helper

* fix(ri/client): type change

* feat(ri/client): render inventories on the ground as chests (latticexyz#80)

* feat(ri/client): render inventories on the ground as chests

* fix(ri/client): remove redundant sprite despawn call

* refactor(ri/client): use ProxyExpand to find Inventory component in Selection UI

* feat(ri): gold shrines (latticexyz#82)

* feat(ri): adding end game (latticexyz#86)

* feat(ri): add emberCrown, escapePortal, and winner components and system

* fix(ri-contracts): change escape system to loop over items for crown instead of check crown owner

* fix(ri-contracts): fix turn length back from dev value

* fix(ri-client): move outcome text out of the way

* feat: map upload, new entity types, and new prototypes (latticexyz#83)

* feat(ri): add prototype dev system

* feat(ri): bulk upload, map, new entities

* feat(ri): terrain types for map generation

Fixed combat properly deleting. Split EntityType and TerrainType into two different values.

* fix(ri): remove hack that was needed when Terrain was part of EntityType

* fix: remove unsed imports

Co-authored-by: Andy Cernera <kooshaba@gmail.com>
Co-authored-by: alvrs <alvarius@lattice.xyz>

* feat: optimistic updates (latticexyz#81)

* feat: expose withOptimisticUpdates from action system

* feat: optimistic updates

* fix: remove type module from ri-contracts because it makes hardhat cry

* feat(recs): allow partial overrides

* feat(recs): change withOptimisitcUpdates api

* docs(recs): rewrite comment for clarity

* feat: add proxy fragments to dynamic queries (latticexyz#85)

* feat: add proxy fragments to queries

* test(recs): add tests for proxy fragments in dymanic queries

* feat(ri): more settlements on map

* fix(ri/contracts): fix imports in Settlement prototype

* feat: add indexers to recs (latticexyz#84)

* chore: add initialBlockNumber and funded deployer key

* fix(ri): prevent entities from attacking themselves

* fix(ri/contracts): disallow copying non-prototype entities

* fix(ri/client): add LocalPosition for the first time on Position update

* feat(ri): donkeys! (latticexyz#87)

* feat: make systems run on init by default (fix phaser hot reload) (latticexyz#91)

* chore: add sync worker config log

* feat: make systems run on init by default (fix phaser hot reload)

* feat(ri): optimistic stamina during movement (latticexyz#88)

* feat(ri): use optimistic stamina calculation for movement

* refactor(ri): using partial updates to update optimistic Stamina in moveEntity

* refactor(ri): split EntityType into Item, Structure, and Unit 💠 (latticexyz#90)

* refactor(ri): split EntityType into Item, Structure, and Unit

* fix(ri): 0 being falsey fucks me at least once a day 🤮

* fix(recs): clone set with indexed entities with values before returning (latticexyz#92)

* refactor(ri): refactor all Type components to use solidity enums (latticexyz#93)

* refactor(ri): remove specific Item components (Gold, EmberCrown)

* refactor(ri/contracts): use enum in contracts for ItemType

* refactor(ri/contracts): use solidity enums for all *Types

* feat(ri): fix aStar bug, add BFS, add indexers to localPosition and P… (latticexyz#89)

* feat(ri): fix aStar bug, add BFS, add indexers to localPosition and Position

* refactor(ri-client): refactor pathing to use CoordMap instead of n^2 grid

* refactor: move CoordMap out of phaserx package into utils package

* fix(ri-client): remove unecessary undefined check in aStar

* feat(cli): suggest available lattice chains in interactive deployer (latticexyz#94)

* fix(ri-contracts): breakout init systems into 2 as workaround for forge script gas estimation issue (latticexyz#95)

* feat(ri): adding Player unit and Death component, moving LibECS from … (latticexyz#98)

* feat(ri): adding Player unit and Death component, moving LibECS from std to ri

* feat(ri): refactor Player unit as Hero, not directly linked to Player entity

* fix(ri-client): fix errant player entity check in moveEntity

* refactor(ri): changing inventory ownership model, inventories are no longer entities (latticexyz#100)

* refactor(ri): changing inventory ownership model, inventories are no longer entities

* fix(ri-contracts): fix empty settlement cost type and map crown prototype name

* fix: optimistic updates, initialBlockNumber, faster initial loading, and more (latticexyz#97)

* feat: make initialBlockNumber part of the deploy script

* chore: tweak bulk uploading

* feat: speed up component schema loading for encoders

* fix: optimistic updates

* feat(client): action queue UI for more observability

* feat: ability to upgrade systems without losing component state

* fix: build client

* fix: add manual gas estimate for moving

* fix: zero pad entity ids if used as eth addresses

* fix(cli): fetch from updated registry

* refactor(ri/client): current local stamina is LocalStamina + Stamina.current

* fix(ri/contracts): fix TransferInventory system to use new System constructor

* fix(ri/scripting): change local constants to point to default world address

Co-authored-by: Andy Cernera <kooshaba@gmail.com>

* fix(ri/contracts): remove old Blueprint components

* fix(ri/contracts): only remove containers when their inv is empty on transfer

* refactor(ri/client): fix up attackEntity function

* refactor(ri/client): split out huge Position system into 4 systems

* fix(ri): remove old comment

* fix(ri/client): remove early return in Position pathfinding system

* refactor(ri): standardize hash IDs, add getItems util (latticexyz#101)

* refactor(ri): unify hash ID format and case

* refactor(ri-client): add util function for getItems

* fix(ri/client): fix typos

* refactor(ri): nit

Co-authored-by: Andy Cernera <kooshaba@gmail.com>

* fix(ri/client): properly despawn sprites when LocalPosition is removed

* refactor(ri-client): remove unnecessary utils folder

* refactor(ri/client): clean up createInputSystem to share more logic and reduce nesting (latticexyz#105)

* refactor(ri/client): clean up createInputSystem to share more logic and reduce nesting

* fix(ri/client): fix right click moving

* refactor(ri): remove hero and death components (latticexyz#106)

deleting hero and death components from contract and client
removing checks to hero and death component in combat and ownership systems
removing hero and death from configs and types

* chore: review

Co-authored-by: Big Nuge <davidkolop@gmail.com>
Co-authored-by: alvarius <89248902+alvrs@users.noreply.github.com>
Co-authored-by: alvrs <alvarius@lattice.xyz>
Co-authored-by: ludens <ludens@lattice.xyz>
  • Loading branch information
5 people committed Jul 25, 2022
1 parent 685341c commit 8bbda73
Show file tree
Hide file tree
Showing 219 changed files with 7,562 additions and 2,749 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@
}
},
"scripts": {
"prepare": "husky install && cd packages/cli && npm link && cd .. && yarn lerna run prepare",
"commit": "cz",
"prettier:check": "prettier --check 'packages/**/*.ts'",
"prettier": "prettier --write 'packages/**/*.ts'",
"lint": "eslint . --ext .ts",
"prepare": "husky install && yarn lerna run prepare",
"lerna:release": "lerna version --conventional-commits --yes",
"lerna:publish": "lerna publish --no-private --force-publish",
"start:ri": "run-pty % yarn workspace ri-contracts run start % yarn workspace ri-client run start"
Expand Down
314 changes: 190 additions & 124 deletions packages/cli/src/commands/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ interface Options {
clientUrl?: string;
netlifySlug?: string;
netlifyPersonalToken?: string;
upgradeSystems?: boolean;
}

export const command = "deploy";
Expand All @@ -50,6 +51,7 @@ export const builder: CommandBuilder<Options, Options> = (yargs) =>
clientUrl: { type: "string" },
netlifySlug: { type: "string" },
netlifyPersonalToken: { type: "string" },
upgradeSystems: { type: "boolean" },
});

export const handler = async (args: Arguments<Options>): Promise<void> => {
Expand Down Expand Up @@ -105,122 +107,168 @@ const getDeployInfo: (args: Arguments<Options>) => Promise<Options> = async (arg
reuseComponents: false,
deployClient: false,
clientUrl: "http://localhost:3000",
upgradeSystems: false,
};

const answers: Options = args.i
? await inquirer.prompt([
{
type: "input",
name: "chainSpec",
default: defaultOptions.chainSpec,
message: "Provide a chainSpec.json location (local or remote)",
when: () => args.chainSpec == null && config.chainSpec == null,
},
{
type: "number",
name: "chainId",
default: defaultOptions.chainId,
message: "Provide a chainId for the deployment",
when: (answers) => answers.chainSpec == null && args.chainId == null && config.chainSpec == null,
},
{
type: "input",
name: "wsRpc",
default: defaultOptions.wsRpc,
message: "Provide a WebSocket RPC endpoint for your deployment",
when: (answers) => answers.chainSpec == null && args.wsRpc == null && config.wsRpc == null,
},
{
type: "input",
name: "rpc",
default: defaultOptions.rpc,
message: "Provide a JSON RPC endpoint for your deployment",
when: (answers) => answers.chainSpec == null && args.rpc == null && config.rpc == null,
validate: (i) => {
if (isValidHttpUrl(i)) return true;
return "Invalid URL";
const { default: fetch } = await importFetch;

// Fetch deployed lattice chains
const latticeChains = args.i
? ((await (await fetch("https://registry.lattice.xyz/api?update=true")).json()) as
| { specUrl: string }[]
| undefined)
: [];

const chainSpecs = latticeChains?.map((e) => e.specUrl) || [];
console.log("Available Lattice chains");
console.log(JSON.stringify(latticeChains, null, 2));

const answers: Options =
args.upgradeSystems && !args.world
? await inquirer.prompt([
{
type: "input",
name: "world",
message: "Provide the address of the World contract to upgrade the systems on.",
when: () => args.world == null && config.world == null,
validate: (i) => {
if (!i || (i[0] == "0" && i[1] == "x" && i.length === 42)) return true;
return "Invalid address";
},
},
},
{
type: "input",
name: "world",
message:
"Provide the address of an existing World contract. (If none is given, a new World will be deployed.)",
when: () => args.world == null && config.world == null,
validate: (i) => {
if (!i || (i[0] == "0" && i[1] == "x" && i.length === 42)) return true;
return "Invalid address";
])
: args.i
? await inquirer.prompt([
{
type: "suggest",
name: "chainSpec",
message: "Provide a chainSpec.json location (local or remote)",
suggestions: chainSpecs,
when: () => args.chainSpec == null && config.chainSpec == null,
},
},
{
type: "list",
name: "reuseComponents",
message: "Reuse existing components?",
choices: [
{ name: "Yes", value: true },
{ name: "No", value: false },
],
default: defaultOptions.reuseComponents,
when: () => args.reuseComponents == null && config.reuseComponents == null,
},
{
type: "input",
name: "deployerPrivateKey",
message: "Enter private key of the deployer account:",
when: () => !args.deployerPrivateKey && !config.deployerPrivateKey,
validate: (i) => {
if (i[0] == "0" && i[1] == "x" && i.length === 66) return true;
return "Invalid private key";
{
type: "number",
name: "chainId",
default: defaultOptions.chainId,
message: "Provide a chainId for the deployment",
when: (answers) => answers.chainSpec == null && args.chainId == null && config.chainSpec == null,
},
},
{
type: "list",
message: "Deploy the client?",
choices: [
{ name: "Yes", value: true },
{ name: "No", value: false },
],
default: defaultOptions.deployClient,
name: "deployClient",
when: () => args.deployClient == null && config.deployClient == null,
},
{
type: "input",
name: "netlifyPersonalToken",
message: "Enter a netlify personal token for deploying the client:",
when: (answers) => answers.deployClient && !args.netlifyPersonalToken && !config.netlifyPersonalToken,
},
{
type: "list",
message: "From which netlify account?",
choices: async (answers) =>
await getNetlifyAccounts(
args.netlifyPersonalToken ?? config.netlifyPersonalToken ?? answers.netlifyPersonalToken!
),
name: "netlifySlug",
when: (answers) => answers.deployClient && !args.netlifySlug && !config.netlifySlug,
},
{
type: "input",
name: "clientUrl",
message: "Enter URL of an already deployed client:",
when: (answers) => !answers.deployClient && !args.clientUrl && !config.clientUrl,
default: "http://localhost:3000",
validate: (i) => {
if (isValidHttpUrl(i)) {
if (i[i.length - 1] === "/") {
return "No trailing slash";
{
type: "input",
name: "wsRpc",
default: defaultOptions.wsRpc,
message: "Provide a WebSocket RPC endpoint for your deployment",
when: (answers) => answers.chainSpec == null && args.wsRpc == null && config.wsRpc == null,
},
{
type: "input",
name: "rpc",
default: defaultOptions.rpc,
message: "Provide a JSON RPC endpoint for your deployment",
when: (answers) => answers.chainSpec == null && args.rpc == null && config.rpc == null,
validate: (i) => {
if (isValidHttpUrl(i)) return true;
return "Invalid URL";
},
},
{
type: "input",
name: "world",
message:
"Provide the address of an existing World contract. (If none is given, a new World will be deployed.)",
when: () => args.world == null && config.world == null,
validate: (i) => {
if (!i || (i[0] == "0" && i[1] == "x" && i.length === 42)) return true;
return "Invalid address";
},
},
{
type: "list",
name: "upgradeSystems",
message: "Only upgrade systems?",
choices: [
{ name: "Yes", value: true },
{ name: "No", value: false },
],
default: defaultOptions.upgradeSystems,
when: (answers) =>
(args.world || config.world || answers.world) &&
args.upgradeSystems == null &&
config.upgradeSystems == null,
},
{
type: "list",
name: "reuseComponents",
message: "Reuse existing components?",
choices: [
{ name: "Yes", value: true },
{ name: "No", value: false },
],
default: defaultOptions.reuseComponents,
when: (answers) =>
!answers.upgradeSystems &&
!args.upgradeSystems &&
!config.upgradeSystems &&
args.reuseComponents == null &&
config.reuseComponents == null,
},
{
type: "input",
name: "deployerPrivateKey",
message: "Enter private key of the deployer account:",
when: () => !args.deployerPrivateKey && !config.deployerPrivateKey,
validate: (i) => {
if (i[0] == "0" && i[1] == "x" && i.length === 66) return true;
return "Invalid private key";
},
},
{
type: "list",
message: "Deploy the client?",
choices: [
{ name: "Yes", value: true },
{ name: "No", value: false },
],
default: defaultOptions.deployClient,
name: "deployClient",
when: () => args.deployClient == null && config.deployClient == null,
},
{
type: "input",
name: "netlifyPersonalToken",
message: "Enter a netlify personal token for deploying the client:",
when: (answers) => answers.deployClient && !args.netlifyPersonalToken && !config.netlifyPersonalToken,
},
{
type: "list",
message: "From which netlify account?",
choices: async (answers) =>
await getNetlifyAccounts(
args.netlifyPersonalToken ?? config.netlifyPersonalToken ?? answers.netlifyPersonalToken!
),
name: "netlifySlug",
when: (answers) => answers.deployClient && !args.netlifySlug && !config.netlifySlug,
},
{
type: "input",
name: "clientUrl",
message: "Enter URL of an already deployed client:",
when: (answers) => !answers.deployClient && !args.clientUrl && !config.clientUrl,
default: "http://localhost:3000",
validate: (i) => {
if (isValidHttpUrl(i)) {
if (i[i.length - 1] === "/") {
return "No trailing slash";
}
return true;
} else {
return "Not a valid URL";
}
return true;
} else {
return "Not a valid URL";
}
},
},
},
])
: ({} as Options);
])
: ({} as Options);

const { default: fetch } = await importFetch;
const chainSpecUrl = args.chainSpec ?? config.chainSpec ?? answers.chainSpec;
const chainSpec =
chainSpecUrl == null
Expand All @@ -238,6 +286,7 @@ const getDeployInfo: (args: Arguments<Options>) => Promise<Options> = async (arg
rpc: args.rpc ?? chainSpec?.rpc ?? config.rpc ?? answers.rpc ?? defaultOptions.rpc,
wsRpc: args.wsRpc ?? chainSpec?.wsRpc ?? config.wsRpc ?? answers.wsRpc ?? defaultOptions.wsRpc,
world: args.world ?? chainSpec?.world ?? config.world ?? answers.world,
upgradeSystems: args.upgradeSystems ?? config.upgradeSystems ?? answers.upgradeSystems,
reuseComponents:
args.reuseComponents ?? config.reuseComponents ?? answers.reuseComponents ?? defaultOptions.reuseComponents,
deployerPrivateKey: args.deployerPrivateKey ?? config.deployerPrivateKey ?? answers.deployerPrivateKey,
Expand Down Expand Up @@ -271,6 +320,35 @@ export const deploy = async (options: Options) => {
let launcherUrl;
let worldAddress;

const cmdArgs = options.upgradeSystems
? [
"workspace",
"ri-contracts",
"forge:deploy",
"--private-keys",
wallet.privateKey,
"--sig",
"upgradeSystems(address,address)",
wallet.address,
options.world || constants.AddressZero,
"--fork-url",
options.rpc!,
]
: [
"workspace",
"ri-contracts",
"forge:deploy",
"--private-keys",
wallet.privateKey,
"--sig",
"deploy(address,address,bool)",
wallet.address,
options.world || constants.AddressZero,
options.reuseComponents ? "true" : "false",
"--fork-url",
options.rpc!,
];

try {
const tasks = new Listr([
{
Expand All @@ -281,25 +359,13 @@ export const deploy = async (options: Options) => {
{
title: "Contracts",
task: async (ctx, task) => {
const child = execa("yarn", [
"workspace",
"ri-contracts",
"forge:deploy",
"--private-keys",
wallet.privateKey,
"--sig",
"deployEmber(address,address,bool)",
wallet.address,
options.world || constants.AddressZero,
options.reuseComponents ? "true" : "false",
"--fork-url",
options.rpc!,
]);
const child = execa("yarn", cmdArgs);
child.stdout?.pipe(task.stdout());
const { stdout } = await child;
const lines = stdout.split("\n");

ctx.worldAddress = worldAddress = findLog(lines, "world: address");
ctx.initialBlockNumber = findLog(lines, "initialBlockNumber: uint256");
task.output = chalk.yellow(`World deployed at: ${chalk.bgYellow.black(ctx.worldAddress)}`);
},
options: { bottomBar: 3 },
Expand Down Expand Up @@ -369,8 +435,8 @@ export const deploy = async (options: Options) => {
clientUrl || ""
}&rpc=${options.rpc || ""}&wsRpc=${options.wsRpc || ""}&chainId=${options.chainId || ""}&dev=${
options.chainId === 31337 || ""
}`;
openurl.open(launcherUrl);
}&initialBlockNumber=${ctx.initialBlockNumber}`;
if (!options.upgradeSystems) openurl.open(launcherUrl);
},
options: { bottomBar: 3 },
},
Expand Down
Loading

0 comments on commit 8bbda73

Please sign in to comment.