pixi-rainman-game-engine 0.3.20 → 0.3.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,6 +8,7 @@ export interface RegistryMap {
8
8
  [MessageBox.currentWinTextRegistryName]: UpdatableTextComponent;
9
9
  [MessageBox.freeSpinTextRegistryName]: UpdatableTextComponent;
10
10
  [MessageBox.possibleWinTextRegistryName]: UpdatableTextComponent;
11
+ [MessageBox.gamePaysTextRegistryName]: UpdatableTextComponent;
11
12
  [MessageBox.registryName]: MessageBox;
12
13
  [SpeedControlButton.registryName]: SpeedControlButton;
13
14
  [Background.registryName]: Background;
@@ -11,6 +11,7 @@ export const SystemSettingsComponent = () => {
11
11
  <CloseModalButton layerId={UI_ITEMS.settings}/>
12
12
  <div className="settings__column">
13
13
  <BetSettings className="bet-desktop__container"/>
14
+ <div className="separator-vertical "/>
14
15
  <UXSettings />
15
16
  </div>
16
17
  </div>);
@@ -15,8 +15,23 @@
15
15
  .settings__title h2 {
16
16
  color: #ec5e27;
17
17
  margin: 0px;
18
- text-decoration: underline;
19
18
  text-transform: uppercase;
19
+ font-weight: bold;
20
+ font-size: 32px;
21
+ @media only screen and (max-width: 600px) {
22
+ font-size: 24px;
23
+ }
24
+ }
25
+
26
+ .separator-vertical {
27
+ width: 1px;
28
+ min-width: 1px;
29
+ height: 100%;
30
+ background: linear-gradient(to bottom, transparent, rgba(255, 255, 255, 0.7), transparent);
31
+ display: block;
32
+ @media only screen and (orientation: landscape), only screen and (orientation: portrait) {
33
+ display: none;
34
+ }
20
35
  }
21
36
 
22
37
  .settings__column {
@@ -28,14 +43,13 @@
28
43
  width: 100%;
29
44
  }
30
45
 
31
- @media only screen and (max-width: 900px) {
46
+ @media only screen and (orientation: landscape), only screen and (orientation: portrait) {
32
47
  .settings__column {
33
48
  flex-direction: column-reverse;
34
49
  overflow-x: hidden;
35
50
  }
36
51
  }
37
-
38
- @media only screen and (max-width: 900px) {
52
+ @media only screen and (orientation: landscape), only screen and (orientation: portrait) {
39
53
  .bet-desktop__container {
40
54
  display: none;
41
55
  }
@@ -19,13 +19,13 @@ export const BetControls = observer(() => {
19
19
  <h2>{i18next.t("totalBet")}</h2>
20
20
  <div className="bet-container__controls">
21
21
  <button disabled={isDisabled} onClick={() => onClick("decrease")} className="bet-container__button" name="bet-minus">
22
- -
22
+ <span>-</span>
23
23
  </button>
24
24
  <div className="bet-container__value">
25
25
  <p>{settingStore.betText}</p>
26
26
  </div>
27
27
  <button disabled={isDisabled} onClick={() => onClick("increase")} className="bet-container__button" name="bet-plus">
28
- +
28
+ <span>+</span>
29
29
  </button>
30
30
  </div>
31
31
  </div>);
@@ -28,6 +28,9 @@
28
28
  text-align: center;
29
29
  color: white;
30
30
  text-transform: uppercase;
31
+ margin-bottom: 12px;
32
+ font-size: 20px;
33
+ color: #ec5e27;
31
34
  }
32
35
 
33
36
  .bet-container__button {
@@ -41,6 +44,15 @@
41
44
  color: white;
42
45
  text-align: center;
43
46
  cursor: pointer;
47
+ position: relative;
48
+ transition: all 0.2s ease-in-out;
49
+ }
50
+
51
+ .bet-container__button span {
52
+ position: absolute;
53
+ top: 50%;
54
+ left: 50%;
55
+ transform: translate(-50%, -50%);
44
56
  }
45
57
 
46
58
  .bet-container__button:disabled {
@@ -49,10 +61,16 @@
49
61
  user-select: none;
50
62
  }
51
63
 
52
- .bet-container__button:active {
53
- background-color: #fdf42550;
54
- color: #fdf425;
55
- border: 2px solid #fdf425;
64
+ .bet-container__button:hover:not(:disabled) {
65
+ background-color: #ec5f274d;
66
+ color: #ec5e27;
67
+ border: 2px solid #ec5e27;
68
+ }
69
+
70
+ .bet-container__button:active:not(:disabled) {
71
+ background-color: #ec5f27b0;
72
+ color: #ec5e27;
73
+ border: 2px solid #ec5e27;
56
74
  }
57
75
 
58
76
  .bet-container__controls {
@@ -61,6 +79,10 @@
61
79
  }
62
80
 
63
81
  @media only screen and (max-width: 900px) {
82
+ .bet-container__controls {
83
+ margin-bottom: 12px;
84
+ }
85
+
64
86
  #bet-layer.modal {
65
87
  width: 90vw;
66
88
  height: fit-content;
@@ -27,6 +27,26 @@
27
27
  border-radius: 34px;
28
28
  }
29
29
 
30
+ @keyframes shine {
31
+ from {
32
+ -webkit-mask-position: 150%;
33
+ }
34
+
35
+ to {
36
+ -webkit-mask-position: -50%;
37
+ }
38
+ }
39
+
40
+ .switch-round-box:hover:not(.switch-round-box--active) {
41
+ -webkit-mask-image: linear-gradient(-75deg, #000 30%, rgba(0, 0, 0, 0.6) 50%, #000 70%);
42
+ -webkit-mask-size: 200%;
43
+ animation: shine 1.5s infinite;
44
+ }
45
+
46
+ .turtle-switch {
47
+ width: 83px;
48
+ }
49
+
30
50
  .turtle-switch-round-box {
31
51
  position: absolute;
32
52
  cursor: pointer;
@@ -89,26 +109,26 @@
89
109
  .switch__text {
90
110
  margin: 0;
91
111
  position: absolute;
92
- top: 5px;
112
+ top: 8px;
93
113
  right: 9px;
94
114
  }
95
115
 
96
116
  .switch__text--active {
97
117
  left: 9px;
98
- color: #fdf425;
118
+ color: #ec5e27;
99
119
  }
100
120
 
101
121
  .switch-round-box--active {
102
- box-shadow: 0 0 1px #fdf425;
103
- background-color: #fdf42550;
104
- border: 2px solid #fdf425;
122
+ box-shadow: 0px 0px 30px 00px rgba(236, 94, 39, 1);
123
+ background-color: #ec5f2778;
124
+ border: 2px solid #ec5e27;
105
125
  }
106
126
 
107
127
  .switch-round-box--active:before {
108
128
  -webkit-transform: translateX(45px);
109
129
  -ms-transform: translateX(45px);
110
130
  transform: translateX(45px);
111
- background-color: #fdf425;
131
+ background-color: #ec5e27;
112
132
  }
113
133
 
114
134
  @media only screen and (max-width: 900px) {
@@ -1,11 +1,12 @@
1
1
  .header-description {
2
- max-width: 200px;
2
+ width: 75%;
3
3
  }
4
4
 
5
5
  .header-description__title {
6
6
  min-width: 200px;
7
7
  margin: 0px;
8
8
  text-transform: uppercase;
9
+ font-weight: bold;
9
10
  }
10
11
 
11
12
  @media only screen and (max-width: 650px) {
@@ -15,8 +16,9 @@
15
16
  }
16
17
 
17
18
  .header-description__text {
18
- max-width: 170px;
19
+ max-width: 90%;
19
20
  margin: 0px;
21
+ opacity: 0.6;
20
22
  }
21
23
 
22
24
  @media only screen and (max-width: 900px) {
@@ -21,14 +21,20 @@
21
21
  width: 100%;
22
22
  }
23
23
 
24
- @media only screen and (max-width: 900px) {
24
+ @media only screen and (orientation: landscape), only screen and (orientation: portrait) {
25
25
  .ux-settings__switch {
26
- width: 250px;
26
+ width: max(250px, 80%);
27
+ }
28
+ .ux-settings__switch:last-child {
29
+ padding-bottom: 20px;
27
30
  }
28
31
  .ux-settings {
29
- width: unset;
32
+ width: 85%;
30
33
  overflow-y: auto;
31
34
  overflow-x: hidden;
32
35
  padding: 0 30px;
33
36
  }
37
+ .ux-settings__switch-container {
38
+ gap: 10px;
39
+ }
34
40
  }
@@ -61,6 +61,7 @@
61
61
  "collect": "COLLECT",
62
62
  "totalBet": "Bet",
63
63
  "buyFreeSpins": "Buy Free Spins",
64
- "possibleWin": "POSSIBLE WIN: "
64
+ "possibleWin": "POSSIBLE WIN: ",
65
+ "gamePaysText": "GAME PAYS: "
65
66
  }
66
67
  }
@@ -64,6 +64,9 @@ export class AbstractFrame extends ResumableContainer {
64
64
  const spineName = this.mysteryFxConfig.mobileSpineName && getDeviceOrientation() === "mobile-portrait"
65
65
  ? this.mysteryFxConfig.mobileSpineName
66
66
  : this.mysteryFxConfig.spineName;
67
+ if (!spineName) {
68
+ return;
69
+ }
67
70
  this.mysteryFxHighlight = new Spine(getSpineData(spineName));
68
71
  this.repositionMysteryFx(x, y);
69
72
  SoundManager.play(SoundTracks.mysteryFxLoop);
@@ -18,14 +18,17 @@ export declare class MessageBox extends Container {
18
18
  static readonly autoSpinTextRegistryName = "autoSpinAmount";
19
19
  static readonly currentWinTextRegistryName = "winAmount";
20
20
  static readonly possibleWinTextRegistryName = "possibleWinAmount";
21
+ static readonly gamePaysTextRegistryName = "gamePaysAmount";
21
22
  private readonly positioningFrame;
22
23
  private readonly autoSpinText;
23
24
  private readonly freeSpinText;
24
25
  private readonly incentiveText;
25
26
  private readonly currentWinText;
26
27
  private readonly possibleWinText;
28
+ private readonly gamePaysText;
27
29
  private winLineIndicator?;
28
30
  private currentWinShown;
31
+ private gamePaysShown;
29
32
  private autoSpinShown;
30
33
  private freeSpinShown;
31
34
  private possibleWinShown;
@@ -45,6 +48,12 @@ export declare class MessageBox extends Container {
45
48
  * @returns {void}
46
49
  */
47
50
  hideCurrentWinText(): void;
51
+ /**
52
+ * Function for hiding game pays text
53
+ * @public
54
+ * @returns {void}
55
+ */
56
+ hideGamePaysText(): void;
48
57
  /**
49
58
  * Function fro hiding possible win text
50
59
  * @public
@@ -105,6 +114,13 @@ export declare class MessageBox extends Container {
105
114
  * @returns {void}
106
115
  */
107
116
  showPossibleWinText(): void;
117
+ /**
118
+ * Displays the game pays text in the message box.
119
+ * It also checks if the text is already shown and if other texts are visible to prevent overlapping.
120
+ * @public
121
+ * @returns {void}
122
+ */
123
+ showGamePaysText(): void;
108
124
  /**
109
125
  * Displays the auto spin text in the message box.
110
126
  * It checks if auto spins are enabled and if the text is already shown.
@@ -23,14 +23,17 @@ export class MessageBox extends Container {
23
23
  static autoSpinTextRegistryName = "autoSpinAmount";
24
24
  static currentWinTextRegistryName = "winAmount";
25
25
  static possibleWinTextRegistryName = "possibleWinAmount";
26
+ static gamePaysTextRegistryName = "gamePaysAmount";
26
27
  positioningFrame;
27
28
  autoSpinText;
28
29
  freeSpinText;
29
30
  incentiveText;
30
31
  currentWinText;
31
32
  possibleWinText;
33
+ gamePaysText;
32
34
  winLineIndicator = undefined;
33
35
  currentWinShown = false;
36
+ gamePaysShown = false;
34
37
  autoSpinShown = false;
35
38
  freeSpinShown = false;
36
39
  possibleWinShown = false;
@@ -50,6 +53,7 @@ export class MessageBox extends Container {
50
53
  this.freeSpinText = new UpdatableTextComponent(MessageBox.freeSpinTextRegistryName, i18n.t("currentFreeSpins"), UPDATABLE_MODES.int, fontSize - 5, new Color(0xffffff).toHex(), () => this.centerTextOnX(this.freeSpinText));
51
54
  this.autoSpinText = new UpdatableTextComponent(MessageBox.autoSpinTextRegistryName, i18n.t("autoSpinsLeft"), UPDATABLE_MODES.int, fontSize - 5, new Color(0xffffff).toHex(), () => this.centerTextOnX(this.autoSpinText));
52
55
  this.currentWinText = new UpdatableTextComponent(MessageBox.currentWinTextRegistryName, i18n.t("currentWin"), UPDATABLE_MODES.money, fontSize + 15, undefined, () => this.centerTextOnX(this.currentWinText));
56
+ this.gamePaysText = new UpdatableTextComponent(MessageBox.gamePaysTextRegistryName, i18n.t("gamePaysText"), UPDATABLE_MODES.money, fontSize + 15, undefined, () => this.centerTextOnX(this.gamePaysText));
53
57
  this.possibleWinText = new UpdatableTextComponent(MessageBox.possibleWinTextRegistryName, i18n.t("possibleWin"), UPDATABLE_MODES.money, fontSize + 15, undefined, () => this.centerTextOnX(this.possibleWinText));
54
58
  this.incentiveText = new Text(sample(i18n.t("idleMessages", { returnObjects: true })[RainMan.componentRegistry.getSpeedLevel()]), {
55
59
  fontFamily: RainMan.config.fontFace,
@@ -60,11 +64,13 @@ export class MessageBox extends Container {
60
64
  });
61
65
  this.incentiveText.y = -25;
62
66
  this.currentWinText.y = -25;
67
+ this.gamePaysText.y = -25;
63
68
  this.possibleWinText.y = -25;
64
69
  this.freeSpinText.y = this.currentWinText.y + this.currentWinText.height / 2 + this.freeSpinText.height / 2;
65
70
  this.autoSpinText.y = this.currentWinText.y + this.currentWinText.height / 2 + this.autoSpinText.height / 2;
66
71
  RainMan.componentRegistry.addMany([
67
72
  this.currentWinText,
73
+ this.gamePaysText,
68
74
  this.autoSpinText,
69
75
  this.freeSpinText,
70
76
  this.possibleWinText
@@ -91,6 +97,17 @@ export class MessageBox extends Container {
91
97
  this.removeChild(this.currentWinText);
92
98
  }
93
99
  }
100
+ /**
101
+ * Function for hiding game pays text
102
+ * @public
103
+ * @returns {void}
104
+ */
105
+ hideGamePaysText() {
106
+ if (this.gamePaysShown) {
107
+ this.gamePaysShown = false;
108
+ this.removeChild(this.gamePaysText);
109
+ }
110
+ }
94
111
  /**
95
112
  * Function fro hiding possible win text
96
113
  * @public
@@ -183,6 +200,7 @@ export class MessageBox extends Container {
183
200
  }
184
201
  this.hideIncentiveText();
185
202
  this.hidePossibleWinText();
203
+ this.hideGamePaysText();
186
204
  if (this.currentWinShown) {
187
205
  return;
188
206
  }
@@ -205,6 +223,23 @@ export class MessageBox extends Container {
205
223
  this.centerTextOnX(this.possibleWinText);
206
224
  this.addChild(this.possibleWinText);
207
225
  }
226
+ /**
227
+ * Displays the game pays text in the message box.
228
+ * It also checks if the text is already shown and if other texts are visible to prevent overlapping.
229
+ * @public
230
+ * @returns {void}
231
+ */
232
+ showGamePaysText() {
233
+ this.hideIncentiveText();
234
+ this.hideCurrentWinText();
235
+ this.hidePossibleWinText();
236
+ if (this.gamePaysShown) {
237
+ return;
238
+ }
239
+ this.gamePaysShown = true;
240
+ this.centerTextOnX(this.gamePaysText);
241
+ this.addChild(this.gamePaysText);
242
+ }
208
243
  /**
209
244
  * Displays the auto spin text in the message box.
210
245
  * It checks if auto spins are enabled and if the text is already shown.
@@ -54,6 +54,7 @@ export declare abstract class AbstractController<T> {
54
54
  protected wasAutoplayEnabledBeforeFreeSpin: boolean;
55
55
  protected setSlowerSpeedForFreeSpins: boolean;
56
56
  shouldStopMobileSpin: boolean;
57
+ disableMessageBoxChange: boolean;
57
58
  protected resolveBigWin?: () => void;
58
59
  protected resolveMysteryWin?: () => void;
59
60
  protected resolveBonusWin?: () => void;
@@ -54,6 +54,7 @@ export class AbstractController {
54
54
  wasAutoplayEnabledBeforeFreeSpin = false;
55
55
  setSlowerSpeedForFreeSpins = false;
56
56
  shouldStopMobileSpin = false;
57
+ disableMessageBoxChange = false;
57
58
  resolveBigWin;
58
59
  resolveMysteryWin;
59
60
  resolveBonusWin;
@@ -361,7 +362,12 @@ export class AbstractController {
361
362
  this.uiController.recentWin = ceilToDecimal(spinLogic.winTotalAmount);
362
363
  this.uiController.totalFreeSpinWinAmount = this._lastWinAmount;
363
364
  }
364
- this.uiController.currentBalance = spinData.balance;
365
+ if (availableFreeSpins > 0) {
366
+ this.uiController.currentBalance = spinData.balance;
367
+ }
368
+ else {
369
+ this.uiController.currentBalance = spinData.balance + this.initData.round_win_amount;
370
+ }
365
371
  this.roundNumber = spinData.getRawData().round_number;
366
372
  RainMan.settingsStore.setRoundNumber(this.roundNumber);
367
373
  if (this._lastWinAmount !== 0) {
@@ -578,7 +584,9 @@ export class AbstractController {
578
584
  * @returns {void}
579
585
  */
580
586
  setMessageBoxBasedOnPhase(phase) {
581
- if (RainMan.settingsStore.isFreeSpinsPlayEnabled && !this.invokeFreeSpinPlateAfterWin) {
587
+ if (RainMan.settingsStore.isFreeSpinsPlayEnabled &&
588
+ !this.invokeFreeSpinPlateAfterWin &&
589
+ !this.disableMessageBoxChange) {
582
590
  this.uiController.messageBox.showCurrentWinText();
583
591
  if (!this.hideFreeSpinsMessageBox) {
584
592
  this.uiController.messageBox.showFreeSpinText();
@@ -147,6 +147,19 @@ export declare class UiController {
147
147
  * @returns {void}
148
148
  */
149
149
  updateShownPossibleWin(): void;
150
+ /**
151
+ * Shows game pays in a bottom panel, if exists
152
+ * @param amount
153
+ * @public
154
+ * @returns {void}
155
+ */
156
+ updateShownGamePays(amount: number): void;
157
+ /**
158
+ * Shows game pays in a bottom panel, if exists
159
+ * @public
160
+ * @returns {void}
161
+ */
162
+ resetGamePaysText(): void;
150
163
  /**
151
164
  * Function for updating shown free spin amount
152
165
  * @public
@@ -214,6 +214,24 @@ export class UiController {
214
214
  this.messageBox.showPossibleWinText();
215
215
  RainMan.componentRegistry.get(MessageBox.possibleWinTextRegistryName).set(this.recentWin);
216
216
  }
217
+ /**
218
+ * Shows game pays in a bottom panel, if exists
219
+ * @param amount
220
+ * @public
221
+ * @returns {void}
222
+ */
223
+ updateShownGamePays(amount) {
224
+ this.messageBox.showGamePaysText();
225
+ RainMan.componentRegistry.get(MessageBox.gamePaysTextRegistryName).update(amount);
226
+ }
227
+ /**
228
+ * Shows game pays in a bottom panel, if exists
229
+ * @public
230
+ * @returns {void}
231
+ */
232
+ resetGamePaysText() {
233
+ RainMan.componentRegistry.get(MessageBox.gamePaysTextRegistryName).set(0);
234
+ }
217
235
  /**
218
236
  * Function for updating shown free spin amount
219
237
  * @public
@@ -143,7 +143,10 @@ export const setTimeScale = (spine, flag) => {
143
143
  * @returns {void}
144
144
  */
145
145
  export const changeResolution = (high) => {
146
- RainMan.app.renderer.resolution = high ? window.devicePixelRatio : 1;
146
+ const lowRes = Math.max(window.devicePixelRatio * 0.5, 1);
147
+ const resolution = high ? window.devicePixelRatio : lowRes;
148
+ RainMan.app.renderer.resolution = resolution;
149
+ RainMan.app.renderer.resize(RainMan.app.screen.width, RainMan.app.screen.height);
147
150
  };
148
151
  /**
149
152
  * Helper function for checking if the value is not null or undefined
@@ -6,6 +6,7 @@ import { UpdatableValueComponent } from "../components";
6
6
  * @augments {UpdatableValueComponent}
7
7
  */
8
8
  export declare class TexturedText extends UpdatableValueComponent {
9
+ private baseFontSize;
9
10
  registryName: string;
10
11
  textureSprite?: Sprite;
11
12
  constructor(registryName: string, text: string, textStyle: ITextStyle, textureName?: string);
@@ -30,4 +31,24 @@ export declare class TexturedText extends UpdatableValueComponent {
30
31
  * @returns {void}
31
32
  */
32
33
  play(): void;
34
+ /**
35
+ * Sets the text style for the value text component.
36
+ * @param {Partial<ITextStyle>} style - The new text style to apply.
37
+ * @public
38
+ * @returns {void}
39
+ */
40
+ setTextStyle(style: Partial<ITextStyle>): void;
41
+ /**
42
+ * Sets base font size
43
+ * @param {number} value new value of the base font size
44
+ * @public
45
+ * @returns {void}
46
+ */
47
+ setBaseFontSize(value: number): void;
48
+ /**
49
+ * Updates current text font size based on current text length and base font size
50
+ * @public
51
+ * @returns {void}
52
+ */
53
+ updateFontSize(): void;
33
54
  }
@@ -10,6 +10,7 @@ import { getTexture } from "../utils";
10
10
  * @augments {UpdatableValueComponent}
11
11
  */
12
12
  export class TexturedText extends UpdatableValueComponent {
13
+ baseFontSize = 190;
13
14
  registryName = "";
14
15
  textureSprite;
15
16
  constructor(registryName, text, textStyle, textureName) {
@@ -33,7 +34,7 @@ export class TexturedText extends UpdatableValueComponent {
33
34
  * @returns {Promise<void>}
34
35
  */
35
36
  async update(newValue) {
36
- this.valueTextComponent.style.fontSize = -10 * new MoneyText(newValue).toString().length + 190;
37
+ this.valueTextComponent.style.fontSize = -10 * new MoneyText(newValue).toString().length + this.baseFontSize;
37
38
  await super.update(newValue, RainMan.config.durationOfActions.updatableTextCountingDuration);
38
39
  }
39
40
  /**
@@ -44,7 +45,7 @@ export class TexturedText extends UpdatableValueComponent {
44
45
  * @returns {void}
45
46
  */
46
47
  randomizeSet(value, _possibleValues) {
47
- this.valueTextComponent.style.fontSize = -10 * new MoneyText(value).toString().length + 190;
48
+ this.valueTextComponent.style.fontSize = -10 * new MoneyText(value).toString().length + this.baseFontSize;
48
49
  super.update(value, 1);
49
50
  }
50
51
  /**
@@ -63,4 +64,30 @@ export class TexturedText extends UpdatableValueComponent {
63
64
  })
64
65
  .start();
65
66
  }
67
+ /**
68
+ * Sets the text style for the value text component.
69
+ * @param {Partial<ITextStyle>} style - The new text style to apply.
70
+ * @public
71
+ * @returns {void}
72
+ */
73
+ setTextStyle(style) {
74
+ this.valueTextComponent.style = { ...this.valueTextComponent.style, ...style };
75
+ }
76
+ /**
77
+ * Sets base font size
78
+ * @param {number} value new value of the base font size
79
+ * @public
80
+ * @returns {void}
81
+ */
82
+ setBaseFontSize(value) {
83
+ this.baseFontSize = value;
84
+ }
85
+ /**
86
+ * Updates current text font size based on current text length and base font size
87
+ * @public
88
+ * @returns {void}
89
+ */
90
+ updateFontSize() {
91
+ this.valueTextComponent.style.fontSize = -10 * super.value.length + this.baseFontSize;
92
+ }
66
93
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pixi-rainman-game-engine",
3
- "version": "0.3.20",
3
+ "version": "0.3.22",
4
4
  "description": "This repository contains all of the mechanics that used in rainman games.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",