ecs.ts 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  1. import { expect } from "chai";
  2. import {
  3. anchor,
  4. web3,
  5. FindComponentPda,
  6. FindEntityPda,
  7. SerializeArgs,
  8. } from "../../clients/bolt-sdk/lib";
  9. import { Direction } from "../framework";
  10. export function ecs(framework) {
  11. describe("ECS", () => {
  12. it("Add entity 1", async () => {
  13. const world = await framework.worldProgram.account.world.fetch(
  14. framework.worldPda,
  15. );
  16. framework.entity1Pda = FindEntityPda({
  17. worldId: world.id,
  18. entityId: world.entities,
  19. });
  20. const instruction = await framework.worldProgram.methods
  21. .addEntity(null)
  22. .accounts({
  23. payer: framework.provider.wallet.publicKey,
  24. world: framework.worldPda,
  25. entity: framework.entity1Pda,
  26. })
  27. .instruction();
  28. const transaction = new anchor.web3.Transaction().add(instruction);
  29. await framework.provider.sendAndConfirm(transaction);
  30. });
  31. it("Add entity 2", async () => {
  32. const world = await framework.worldProgram.account.world.fetch(
  33. framework.worldPda,
  34. );
  35. framework.entity2Pda = FindEntityPda({
  36. worldId: world.id,
  37. entityId: world.entities,
  38. });
  39. const instruction = await framework.worldProgram.methods
  40. .addEntity(null)
  41. .accounts({
  42. payer: framework.provider.wallet.publicKey,
  43. world: framework.worldPda,
  44. entity: framework.entity2Pda,
  45. })
  46. .instruction();
  47. const transaction = new anchor.web3.Transaction().add(instruction);
  48. await framework.provider.sendAndConfirm(transaction);
  49. });
  50. it("Add entity 3", async () => {
  51. const world = await framework.worldProgram.account.world.fetch(
  52. framework.worldPda,
  53. );
  54. const entity3Pda = FindEntityPda({
  55. worldId: world.id,
  56. entityId: world.entities,
  57. });
  58. const instruction = await framework.worldProgram.methods
  59. .addEntity(null)
  60. .accounts({
  61. payer: framework.provider.wallet.publicKey,
  62. world: framework.worldPda,
  63. entity: entity3Pda,
  64. })
  65. .instruction();
  66. const transaction = new anchor.web3.Transaction().add(instruction);
  67. await framework.provider.sendAndConfirm(transaction);
  68. });
  69. it("Add entity 4 (with seed)", async () => {
  70. const world = await framework.worldProgram.account.world.fetch(
  71. framework.worldPda,
  72. );
  73. const seed = Buffer.from("custom-seed");
  74. framework.entity4Pda = FindEntityPda({ worldId: world.id, seed });
  75. const instruction = await framework.worldProgram.methods
  76. .addEntity(seed)
  77. .accounts({
  78. payer: framework.provider.wallet.publicKey,
  79. world: framework.worldPda,
  80. entity: framework.entity4Pda,
  81. })
  82. .instruction();
  83. const transaction = new anchor.web3.Transaction().add(instruction);
  84. await framework.provider.sendAndConfirm(transaction);
  85. });
  86. it("Initialize Velocity Component on Entity 1 (with seed)", async () => {
  87. const componentId = framework.exampleComponentVelocity.programId;
  88. framework.componentVelocityEntity1Pda = FindComponentPda({
  89. componentId,
  90. entity: framework.entity1Pda,
  91. seed: "component-velocity",
  92. });
  93. const instruction = await framework.worldProgram.methods
  94. .initializeComponent()
  95. .accounts({
  96. payer: framework.provider.wallet.publicKey,
  97. entity: framework.entity1Pda,
  98. data: framework.componentVelocityEntity1Pda,
  99. componentProgram: componentId,
  100. authority: framework.worldProgram.programId,
  101. })
  102. .instruction();
  103. const transaction = new anchor.web3.Transaction().add(instruction);
  104. await framework.provider.sendAndConfirm(transaction);
  105. });
  106. it("Initialize Position Component on Entity 1", async () => {
  107. const componentId = framework.exampleComponentPosition.programId;
  108. framework.componentPositionEntity1Pda = FindComponentPda({
  109. componentId,
  110. entity: framework.entity1Pda,
  111. });
  112. const instruction = await framework.worldProgram.methods
  113. .initializeComponent()
  114. .accounts({
  115. payer: framework.provider.wallet.publicKey,
  116. entity: framework.entity1Pda,
  117. data: framework.componentPositionEntity1Pda,
  118. componentProgram: componentId,
  119. authority: framework.worldProgram.programId,
  120. })
  121. .instruction();
  122. const transaction = new anchor.web3.Transaction().add(instruction);
  123. await framework.provider.sendAndConfirm(transaction);
  124. });
  125. it("Initialize Position Component on Entity 2", async () => {
  126. const componentId = framework.exampleComponentPosition.programId;
  127. const componentPda = FindComponentPda({
  128. componentId,
  129. entity: framework.entity2Pda,
  130. });
  131. const instruction = await framework.worldProgram.methods
  132. .initializeComponent()
  133. .accounts({
  134. payer: framework.provider.wallet.publicKey,
  135. entity: framework.entity2Pda,
  136. data: componentPda,
  137. componentProgram: componentId,
  138. authority: framework.worldProgram.programId,
  139. })
  140. .instruction();
  141. const transaction = new anchor.web3.Transaction().add(instruction);
  142. await framework.provider.sendAndConfirm(transaction);
  143. });
  144. it("Initialize Position Component on Entity 4", async () => {
  145. const componentId = framework.exampleComponentPosition.programId;
  146. framework.componentPositionEntity4Pda = FindComponentPda({
  147. componentId,
  148. entity: framework.entity4Pda,
  149. });
  150. const instruction = await framework.worldProgram.methods
  151. .initializeComponent()
  152. .accounts({
  153. payer: framework.provider.wallet.publicKey,
  154. entity: framework.entity4Pda,
  155. data: framework.componentPositionEntity4Pda,
  156. componentProgram: componentId,
  157. authority: framework.worldProgram.programId,
  158. })
  159. .instruction();
  160. const transaction = new anchor.web3.Transaction().add(instruction);
  161. await framework.provider.sendAndConfirm(transaction);
  162. });
  163. it("Check Position on Entity 1 is default", async () => {
  164. const position =
  165. await framework.exampleComponentPosition.account.position.fetch(
  166. framework.componentPositionEntity1Pda,
  167. );
  168. expect(position.x.toNumber()).to.equal(0);
  169. expect(position.y.toNumber()).to.equal(0);
  170. expect(position.z.toNumber()).to.equal(0);
  171. });
  172. it("Apply Simple Movement System (Up) on Entity 1", async () => {
  173. const instruction = await framework.worldProgram.methods
  174. .apply(SerializeArgs({ direction: Direction.Up }))
  175. .accounts({
  176. authority: framework.provider.wallet.publicKey,
  177. boltSystem: framework.systemSimpleMovement.programId,
  178. world: framework.worldPda,
  179. sessionToken: null,
  180. })
  181. .remainingAccounts([
  182. {
  183. pubkey: framework.exampleComponentPosition.programId,
  184. isSigner: false,
  185. isWritable: false,
  186. },
  187. {
  188. pubkey: framework.componentPositionEntity1Pda,
  189. isSigner: false,
  190. isWritable: true,
  191. },
  192. ])
  193. .instruction();
  194. const transaction = new anchor.web3.Transaction().add(instruction);
  195. await framework.provider.sendAndConfirm(transaction);
  196. const position =
  197. await framework.exampleComponentPosition.account.position.fetch(
  198. framework.componentPositionEntity1Pda,
  199. );
  200. expect(position.x.toNumber()).to.equal(0);
  201. expect(position.y.toNumber()).to.equal(1);
  202. expect(position.z.toNumber()).to.equal(0);
  203. });
  204. it("Apply Simple Movement System (Right) on Entity 1", async () => {
  205. const instruction = await framework.worldProgram.methods
  206. .apply(SerializeArgs({ direction: Direction.Right }))
  207. .accounts({
  208. authority: framework.provider.wallet.publicKey,
  209. boltSystem: framework.systemSimpleMovement.programId,
  210. world: framework.worldPda,
  211. sessionToken: null,
  212. })
  213. .remainingAccounts([
  214. {
  215. pubkey: framework.exampleComponentPosition.programId,
  216. isSigner: false,
  217. isWritable: false,
  218. },
  219. {
  220. pubkey: framework.componentPositionEntity1Pda,
  221. isSigner: false,
  222. isWritable: true,
  223. },
  224. ])
  225. .instruction();
  226. const transaction = new anchor.web3.Transaction().add(instruction);
  227. await framework.provider.sendAndConfirm(transaction);
  228. const position =
  229. await framework.exampleComponentPosition.account.position.fetch(
  230. framework.componentPositionEntity1Pda,
  231. );
  232. expect(position.x.toNumber()).to.equal(1);
  233. expect(position.y.toNumber()).to.equal(1);
  234. expect(position.z.toNumber()).to.equal(0);
  235. });
  236. it("Apply Fly System on Entity 1", async () => {
  237. const instruction = await framework.worldProgram.methods
  238. .apply(SerializeArgs())
  239. .accounts({
  240. authority: framework.provider.wallet.publicKey,
  241. boltSystem: framework.systemFly.programId,
  242. world: framework.worldPda,
  243. sessionToken: null,
  244. })
  245. .remainingAccounts([
  246. {
  247. pubkey: framework.exampleComponentPosition.programId,
  248. isSigner: false,
  249. isWritable: false,
  250. },
  251. {
  252. pubkey: framework.componentPositionEntity1Pda,
  253. isSigner: false,
  254. isWritable: true,
  255. },
  256. ])
  257. .instruction();
  258. const transaction = new anchor.web3.Transaction().add(instruction);
  259. await framework.provider.sendAndConfirm(transaction);
  260. const position =
  261. await framework.exampleComponentPosition.account.position.fetch(
  262. framework.componentPositionEntity1Pda,
  263. );
  264. expect(position.x.toNumber()).to.equal(1);
  265. expect(position.y.toNumber()).to.equal(1);
  266. expect(position.z.toNumber()).to.equal(1);
  267. });
  268. it("Apply System Velocity on Entity 1", async () => {
  269. const instruction = await framework.worldProgram.methods
  270. .apply(SerializeArgs())
  271. .accounts({
  272. authority: framework.provider.wallet.publicKey,
  273. boltSystem: framework.systemApplyVelocity.programId,
  274. world: framework.worldPda,
  275. sessionToken: null,
  276. })
  277. .remainingAccounts([
  278. {
  279. pubkey: framework.exampleComponentVelocity.programId,
  280. isSigner: false,
  281. isWritable: false,
  282. },
  283. {
  284. pubkey: framework.componentVelocityEntity1Pda,
  285. isSigner: false,
  286. isWritable: true,
  287. },
  288. {
  289. pubkey: framework.exampleComponentPosition.programId,
  290. isSigner: false,
  291. isWritable: false,
  292. },
  293. {
  294. pubkey: framework.componentPositionEntity1Pda,
  295. isSigner: false,
  296. isWritable: true,
  297. },
  298. ])
  299. .instruction();
  300. const transaction = new anchor.web3.Transaction().add(instruction);
  301. await framework.provider.sendAndConfirm(transaction);
  302. const velocity =
  303. await framework.exampleComponentVelocity.account.velocity.fetch(
  304. framework.componentVelocityEntity1Pda,
  305. );
  306. expect(velocity.x.toNumber()).to.equal(10);
  307. expect(velocity.y.toNumber()).to.equal(0);
  308. expect(velocity.z.toNumber()).to.equal(0);
  309. expect(velocity.lastApplied.toNumber()).to.not.equal(0);
  310. const position =
  311. await framework.exampleComponentPosition.account.position.fetch(
  312. framework.componentPositionEntity1Pda,
  313. );
  314. expect(position.x.toNumber()).to.greaterThan(1);
  315. expect(position.y.toNumber()).to.equal(1);
  316. expect(position.z.toNumber()).to.equal(1);
  317. });
  318. it("Apply System Velocity on Entity 1, with Clock external account", async () => {
  319. const instruction = await framework.worldProgram.methods
  320. .apply(SerializeArgs())
  321. .accounts({
  322. authority: framework.provider.wallet.publicKey,
  323. boltSystem: framework.systemApplyVelocity.programId,
  324. world: framework.worldPda,
  325. sessionToken: null,
  326. })
  327. .remainingAccounts([
  328. {
  329. pubkey: framework.exampleComponentVelocity.programId,
  330. isSigner: false,
  331. isWritable: false,
  332. },
  333. {
  334. pubkey: framework.componentVelocityEntity1Pda,
  335. isSigner: false,
  336. isWritable: true,
  337. },
  338. {
  339. pubkey: framework.exampleComponentPosition.programId,
  340. isSigner: false,
  341. isWritable: false,
  342. },
  343. {
  344. pubkey: framework.componentPositionEntity1Pda,
  345. isSigner: false,
  346. isWritable: true,
  347. },
  348. {
  349. pubkey: framework.worldProgram.programId, // world program ID is the end of components delimiter
  350. isSigner: false,
  351. isWritable: false,
  352. },
  353. {
  354. pubkey: new web3.PublicKey(
  355. "SysvarC1ock11111111111111111111111111111111",
  356. ),
  357. isWritable: false,
  358. isSigner: false,
  359. },
  360. ])
  361. .instruction();
  362. const transaction = new anchor.web3.Transaction().add(instruction);
  363. await framework.provider.sendAndConfirm(transaction);
  364. const position =
  365. await framework.exampleComponentPosition.account.position.fetch(
  366. framework.componentPositionEntity1Pda,
  367. );
  368. expect(position.x.toNumber()).to.greaterThan(1);
  369. expect(position.y.toNumber()).to.equal(1);
  370. expect(position.z.toNumber()).to.equal(300);
  371. });
  372. it("Apply Fly System on Entity 4", async () => {
  373. const instruction = await framework.worldProgram.methods
  374. .apply(SerializeArgs())
  375. .accounts({
  376. authority: framework.provider.wallet.publicKey,
  377. boltSystem: framework.systemFly.programId,
  378. world: framework.worldPda,
  379. sessionToken: null,
  380. })
  381. .remainingAccounts([
  382. {
  383. pubkey: framework.exampleComponentPosition.programId,
  384. isSigner: false,
  385. isWritable: false,
  386. },
  387. {
  388. pubkey: framework.componentPositionEntity4Pda,
  389. isSigner: false,
  390. isWritable: true,
  391. },
  392. ])
  393. .instruction();
  394. const transaction = new anchor.web3.Transaction().add(instruction);
  395. await framework.provider.sendAndConfirm(transaction);
  396. const position =
  397. await framework.exampleComponentPosition.account.position.fetch(
  398. framework.componentPositionEntity4Pda,
  399. );
  400. expect(position.x.toNumber()).to.equal(0);
  401. expect(position.y.toNumber()).to.equal(0);
  402. expect(position.z.toNumber()).to.equal(1);
  403. });
  404. });
  405. }