@urso/core 0.8.21 → 0.8.23

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.
package/README.md CHANGED
@@ -18,207 +18,759 @@ require('./app/config/load'); // your game application
18
18
  window.onload = Urso.runGame; //run game
19
19
  ```
20
20
 
21
- ### Beginning ###
22
- Having cloned the repository to yourself locally, you must install all the game dependencies before starting.
21
+ ### Table of Contents ###
22
+
23
+ 1. Getting Started
24
+ 2. Project Structure
25
+ 3. Engine Architecture and Launch Process
26
+ 4. Objects Required for Game Launch
27
+ 5. Scenes, Scene Sizes, Templates, Components and Simple Objects
28
+ 6. Component Connection and Organization
29
+ 7. Object Visibility Order (Layers)
30
+ 8. Working with Scene Objects (Search, Selectors)
31
+ 9. Event Routers and Event-Driven Model (Observer)
32
+ 10. Dynamic Scene Object Creation
33
+ 11. Working with Classes and Entities
34
+ 12. Adding Sound and Sound/Event Mapping Configuration
35
+ 13. LazyLoad Mechanism (Asset Loading Groups)
36
+ 14. States Manager and Components.StateDriven
37
+ 15. LayersSwitcher Component
38
+ 16. Modifications and Mixins
39
+ 17. Transitions for Objects
40
+ 18. Game Text Localization
41
+ 19. Transport
42
+ 20. Additional Reference Sections
43
+ - 20.1. Core Modules (Lib)
44
+ - 20.2. Additional Information about Templates and Scenes
45
+ - 20.3. Practical Recommendations, Debugging, Profiling
46
+ - 20.4. Examples and API Reference (Compatible Elements)
47
+ 21. Extra (BrowserEvents, PixiPatch)
48
+ 22. Types (Urso.types)
49
+ 23. Events (Urso.events)
50
+ 24. Practical Patterns and Recommendations
51
+ 25. Optimization and Debugging
52
+ 26. FAQ
53
+ 27. Examples from A to Z
54
+ 28. API Reference
55
+ 29. Appendices
56
+ 30. Code Examples
57
+ 31. Links
58
+
59
+ ------------------
60
+
61
+ ### 1. Getting Started ###
62
+ ------------------
63
+ After cloning the repository locally, you need to install all game dependencies before launching.
64
+
65
+ Game dependencies are installed with commands:
66
+ - yarn
67
+ - npm install
68
+
69
+ After installing dependencies, to launch the game you need to execute:
70
+ - yarn start
71
+ - npm run start
72
+
73
+ ### 2. Project Structure ###
74
+ --------------------
75
+ Game source code and resources are located in:
76
+ - src/app — source code (application)
77
+ - src/assets — resources (assets)
78
+
79
+ Each game must include:
80
+ - src/app/config/load.js — connection of all modules (js files), as well as game inheritance chain specification.
81
+ - src/app/config/main.js — setting important game parameters (name, default scene).
82
+ - src/js/index.js — application entry point. Engine code is connected through dependencies, load.js and main.js of the game. Once all engine files are loaded, you need to launch the application using Urso.runGame() function (usually on window.onload).
83
+
84
+ ### 3. Engine Architecture and Launch Process ###
85
+ ------------------------------------------
86
+ The game depends on Core by default.
87
+
88
+ Core consists of:
89
+ - Third-party libraries (Pixi, Howler...).
90
+ - Set of interfaces to these libraries.
91
+ - Transport module.
92
+ - Base components.
93
+ - Sound logic and button states.
94
+ - Game launch logic (Urso.Core.App).
95
+
96
+ After game launch begins, Core, going through established dependencies, will create all namespaces, all necessary objects and methods for game operation (see src/js/app.js in Core repository). Then it will call the run method.
97
+
98
+ Urso.Game assembly occurs based on extendingChain config (ConfigMain)
99
+ For example, if we defined game files in App namespace (window.Urso.App) then extendingChain should look as follows:
100
+ Urso.config.extendingChain = ['Urso.Core', 'Urso.App'];
101
+
102
+ Urso.runGame method in turn will begin loading the default scene using the scene manager.
103
+
104
+ ### 4. Objects Required for Game Launch ###
105
+ ------------------------------------
106
+ - Urso.helper — contains a set of helper methods for developer convenience (see src/js/lib/helper.js in Core repository).
107
+ - Urso.observer — provides event-driven model operation (see src/js/modules/observer in Core repository).
108
+ - Urso.cache — provides work with loaded resources (see src/js/lib/cache.js in Core repository).
109
+ - Urso.device — contains a set of methods for getting data from the device on which the game is running (see src/js/lib/device.js in Core repository).
110
+ - Urso.loader — wrapper class over standard PIXI resource loader (see src/js/lib/loader.js in Core repository).
111
+ - Urso.localData — provides work with local storage inside the game (see src/js/lib/localData.js in Core repository).
112
+ - Urso.assets — contains resource loading logic (see src/js/modules/assets in Core repository).
113
+ - Urso.logic — contains event router logic (see src/js/modules/logic in Core repository).
114
+ - Urso.objects — scene object creation logic (see src/js/modules/objects in Core repository).
115
+ - Urso.scenes — scene manager responsible for creating, displaying, scene transitions (see src/js/modules/scenes in Core repository).
116
+ - Urso.soundManager — manager for working with sounds (see src/js/modules/soundManager in Core repository).
117
+ - Urso.statesManager — manager for working with states (see src/js/modules/statesManager in Core repository).
118
+ - Urso.template — templating engine that provides work with templates (see src/js/modules/template in Core repository).
119
+ - Urso.browserEvents — browser event translator to game (see src/js/extra/browserEvents.js in Core repository).
120
+
121
+ ### 5. Scenes, Scene Sizes, Templates, Components and Simple Objects ###
122
+ ----------------------------------------------------------------
123
+ Scene — a set of objects that are present on screen and display some specific game state (main menu, loading screen, game level).
124
+
125
+ Canvas will occupy maximum available space on the page, based on proportions set in ModulesScenesResolutionsConfig, and parent scene container sizes (virtual pixels) will be determined based on ModulesScenesResolutionsConfig parameters.
126
+
127
+ If adaptive parameter is set to true, then canvas will occupy all available space, and scene sizes will be no less than specified, but one side may be increased to occupy maximum available space on the page. In this case adaptiveConfig starts working. You can set stretching boundaries for each orientation in it.
128
+
129
+ How the scene should look is described in the scene template (for example src/app/templates/scenes/play.js).
130
+
131
+ Template — includes descriptions of styles, resources and objects (simple and components) that need to be created.
132
+
133
+ A separate template group from the list of assets and objects is possible, for example src/app/templates/groups/testGroup.js, and displaying this group on the scene (see src/app/templates/scenes/play.js).
134
+
135
+ Styles are implemented through classes similar to CSS classes. Adding a class to an object automatically applies properties described in styles to it. You can use parameters for objects in styles and control them.
136
+
137
+ Assets — all resources in the game (images, text blocks, buttons, etc.). Asset set automatically gets into the loading list. Asset parameters are located (see src/js/modules/assets/baseModel in Core repository). Asset access is performed, for example, by key specified in asset group.
138
+
139
+ Simple objects — objects such as image, text, container, spine, etc. (see src/js/modules/objects/models in Core repository).
140
+
141
+ When creating a scene object, the templating engine collects all necessary assets and adds them to loading. After loading completion, scene manager begins creating all objects and components. Once components and objects are created — the scene is displayed on screen.
142
+
143
+ Built-in Components
144
+ - Loader — loading progress display
145
+ - Debug — debug metrics
146
+ - Fullscreen — fullscreen mode switching
147
+ - DeviceRotate — UI management with "wrong" orientation
148
+ - StateDriven — base state manager dependent component
149
+ - LayersSwitcher, SoundInitialPopup — service/utility (when available)
150
+
151
+ General best practices for components
152
+ - Don't interact between components directly — only through Observer
153
+ - Local subscriptions
154
+ - Selectors for searching inside component through this.common.find/One/All
23
155
 
24
- Game dependencies are installing with yarn or npm install commands.
156
+ ### 6. Component Connection and Organization ###
157
+ ----------------------------------------
158
+ To add a component, in src/app/config/load.js you need to specify the path to component name and in the component folder specify all files that need to be loaded into the game.
25
159
 
26
- After installing the dependencies, you need to run the command yarn start or npm run start to start the game.
27
-
28
- ### How its working? ###
29
- The source code and assets of the game are located in src/app and src/assets.
160
+ Example:
161
+ - In src/app/config/load.js specify require('../components/_info'); where components — folder name with components.
162
+ - _info file where all js-files of current component are connected.
30
163
 
31
- Each game must necessarily include the following:
32
- - src/app/config/load.js - connecting all modules (js files), as well as specifying the inheritance chain of the game.
33
- - src/app/config/main.js - important parameters for the game (name, scene by default)
34
- - src/js/index.js is the entry point of the application. The engine code is connected there through the dependencies, load.js and main.js of the game. As soon as all the engine files are loaded, you need to launch the application using the Urso.runGame() function (usually on window.onload)
164
+ Components can consist of multiple simple objects, contain different logic, perform actions depending on game events. Component implements MVC-pattern modification, where:
165
+ - controller external interface and event handlers (subscriptions).
166
+ - service logic.
167
+ - view interaction with scene objects.
168
+ - template — set of simple objects related to component.
169
+
170
+ Each component must contain controller; other files are added optionally, depending on the task.
35
171
 
36
- The default game relies on Core.
172
+ Component interaction rules:
173
+ - Components should not independently interact with other components or know about their existence.
174
+ - Components can use helper libraries directly, for example, Urso.localData and Urso.helper. Communication with other entities should occur through events (Urso.observer).
37
175
 
38
- Core is: third-party libraries (Pixi, Howler ...), interfaces to these libraries, a transport module, a base component, logic for sounds and buttons states, and logic for launching a game (Urso.Core.App).
176
+ Urso.localData object (cache) where you can write and get parameters for further work:
177
+ - Urso.localData.set(key, value) — parameter writing.
178
+ - Urso.localData.get(name) — value getting.
39
179
 
40
- After starting the game, Core will create all the namespaces, all the necessary objects and methods for the game to work (see src/js/app.js in the Core repository). Next, it will call the run method.
41
-
42
- ### Objects required to run the game: ###
43
- - Urso.helper - contains a set of helper methods for the convenience of the developer (see src/js/lib/helper.js in the Core repository);
44
- - Urso.observer - provides an event-driven model of the game (see src/js/modules/observer in the Core repository);
45
- - Urso.cache - provides work with loaded resources (see src/js/lib/cache.js in the Core repository);
46
- - Urso.device - contains a set of methods for receiving data from the device on which the game is running (see src/js/lib/device.js in the Core repository);
47
- - Urso.loader - wrapper class over the standard PIXI resource loader (see src/js/lib/loader.js in the Core repository);
48
- - Urso.localData - provides work with local storage inside the game (see src/js/lib/localData.js in the Core repository);
49
- - Urso.assets - contains the logic for working with resource loading (see src/js/modules/assets in the Core repository);
50
- - Urso.logic - contains the logic of event routers (see src/js/modules/logic in the Core repository);
51
- - Urso.objects - the logic for creating scene objects (see src/js/modules/objects in the Core repository);
52
- - Urso.scenes - scene manager responsible for creating, displaying, scene transitions (see src/js/modules/scenes in the Core repository);
53
- - Urso.soundManager - manager for working with sounds (see src/js/modules/soundManager in the Core repository);
54
- - Urso.statesManager - a manager for working states (see src/js/modules/statesManager in the Core repository);
55
- - Urso.template - template engine that provides work with templates (see src/js/modules/template in the Core repository);
56
- - Urso.browserEvents - translator of browser events into the game (see src/js/extra/browserEvents.js in the Core repository);
180
+ ### 7. Object Visibility Order (Layers) ###
181
+ ------------------------------------
182
+ All objects have their visibility order layer on scene. Each object can be behind or in front of another object.
57
183
 
58
- The Urso.runGame method, in turn, will start loading the default scene using the scene manager.
59
-
60
-
61
- ### Scenes, templates, components and simple objects ###
62
- Scene (scene) - a set of objects that are present on the screen and display some specific state of the game (main menu, loading screen, level in the game).
184
+ Order is implemented as follows:
185
+ - Top object specified in code (in object list, for example on scene) will be behind the object specified below it in the list — i.e., in the background.
63
186
 
64
- How the scene should look is described in the template (for example src/app/templates/scenes/play.js).
187
+ ### 8. Working with Scene Objects (Search, Selectors) ###
188
+ --------------------------------------------------
189
+ Tools for working with scene objects (and from console):
190
+ - this.common.find — returns false/object/collection (Urso.find('selector') for console access).
191
+ - this.common.findOne — returns false/object (Urso.findOne('^name') for console access).
192
+ - this.common.findAll('.class') — returns false/collection (Urso.findAll('.class') for console access).
65
193
 
66
- Template (templates) - Template includes descriptions of styles, resources and objects (simple and components) that need to be created.
194
+ Search area:
195
+ - this.common.find() — search inside current component.
196
+ - Urso.find() — search at entire game level.
67
197
 
68
- Styles are implemented through classes, similar to classes in CSS.
198
+ Search modifier first symbol of passed argument:
199
+ - '^' — search by name;
200
+ - '.' — search by class;
201
+ - '#' — search by identifier (id);
202
+ - '' — if not specified, search by object type.
69
203
 
70
- Adding a class to an object automatically applies the properties described in the styles to it.
204
+ Selector combination of modifier and searched name. Example: '.logo' will search for objects that have 'logo' in class.
71
205
 
72
- The set of assets is automatically added to the download list.
206
+ Combined selectors:
207
+ - Urso.find('^nameContainer .classText') — search in '^nameContainer' object for objects with 'classText' class at any nesting level.
73
208
 
74
- For objects, the procedure for creating them on the scene is described.
209
+ ### 9. Event Routers and Event-Driven Model (Observer) ###
210
+ ---------------------------------------------------
211
+ Event routers, using Urso.observer, control the state of entire game and individual components.
75
212
 
76
- The template itself cannot change the states of objects.
213
+ The engine has a set of ready events (see src/js/modules/observer/events.js in Core repository).
77
214
 
78
- Components - Components can consist of many simple objects and unlike templates, their state can be controlled by event routers via Urso.observer.
215
+ Core implements event router:
216
+ - Sounds — router controlling sound playback (see src/js/modules/logic/sounds in Core repository).
217
+ Similarly, you can organize logic of other entities.
79
218
 
80
- Components should not independently interact with other components or be aware of their existence.
219
+ Working with event-driven model is performed by methods:
220
+ - this.addListener('event.name', callback, isGlobal) — subscription.
221
+ - this.removeListener('event.name', callback, isGlobal) — unsubscription.
222
+ - this.emit('event.name', params, delay) — event generation.
81
223
 
82
- Components know and can use directly only helper libraries such as Urso.localData and Urso.helper. Communication with other entities should occur through events (Urso.observer).
224
+ Explanations:
225
+ - First argument — event name.
226
+ - Second — function called when event triggers.
227
+ - Third argument isGlobal — interception mode: locally (within current scene) or globally (for all scenes).
83
228
 
84
- The component implements a modification of the mvc pattern, where:
85
-
86
- - controller should contain only the external interface and event handlers (event subscriptions);
87
- - service contains all the logic;
88
- - view interacts with scene objects;
89
- - template contains a set of simple objects that refer to this component
229
+ Recommendations:
230
+ - Perform subscription in _subscribeOnce method (call when creating class instance). Method will be called automatically when creating class using Urso.getInstance(...) class factory.
231
+ - At component level subscribe in controller.
232
+ - For components it's desirable to use local subscription.
90
233
 
91
- Simple objects (src/js/modules/objects/models) - Objects such as image, text, container, spine, etc.
234
+ Console access:
235
+ - Urso.observer.add — analog of this.addListener.
236
+ - Urso.observer.remove — analog of this.removeListener.
237
+ - Urso.observer.fire — analog of this.emit.
92
238
 
93
- When creating a scene object, the template engine collects all the necessary assets and adds them to the download.
94
-
95
- After the download is complete, the scene manager starts creating all objects and components.
96
-
97
- As soon as the components and objects are created, the scene is displayed on the screen.
98
-
99
- Changes to the global state of the game and individual components occur in event routers. Also available is Urso.statesManager for switching game states through a set of Action objects.
100
-
101
-
102
- ### Event routers and working with the event-driven model (observer) ###
103
- Working with the event-driven model is carried out by the following methods:
104
- - this.addListener('event.name', callback, isGlobal) - used to subscribe to event 'event.name'.
105
- - this.removeListener('event.name', callback, isGlobal) - used to unsubscribe from event 'event.name'.
106
-
107
- The first argument is the name of the event.
108
-
109
- The second argument is a method (function) that will be executed in case of an event triggering.
110
-
111
- The event can be intercepted locally (within the current scene) and globally (for all scenes). Regulated by the third argument (isGlobal) when subscribing.
112
-
113
- It is recommended to subscribe inside the special functions _subscribe or _subscribeOnce, which are automatically called when the class is instantiated.
114
-
115
- At the component level, we recommend that you subscribe at the controller level.
116
-
117
- - this.emit('event.name', params, delay) - used to generate event 'event.name'.
118
-
119
- From the console observer is available with commands:
120
- - Urso.observer.add - analog of this.addListener for access from the console
121
- - Urso.observer.remove - analog of this.removeListener for console access
122
- - Urso.observer.fire - analogue of this.emit for access from the console
123
-
124
- It is desirable to use only local subscriptions for components.
125
-
126
-
127
- ### States Manager ###
128
- The state manager uses a collection of Action objects (src\js\modules\statesManager\configStates.js) and optionally StateDriven components.
129
-
130
- Action logic objects are described in src\js\modules\statesManager\configActions.js.
131
-
132
- When an attempt is made to activate an Action, the guard method is run, which returns true if the Action can be activated or false if not.
133
-
134
- If the StateDriven component is used, it automatically registers its guard with the state manager and there is no need to override the guard in the Action.
135
-
136
-
137
- States are configured by specifying the name of the state and the type of transition between Action:
138
- ```js
139
- STATE_NAME : { action: 'action_name' } // the state contains one Action and ends after it ends.
140
- ```
141
-
142
- ```js
143
- STATE_NAME : {
144
- all: [
145
- { action: 'action_0_name' },
146
- { action: 'action_1_name' }
147
- ]
148
- } // state contains a collection of Action and is completed after all Actions have completed.
149
- ```
150
-
151
- ```js
152
- STATE_NAME : {
153
- race: [
154
- { action: 'action_0_name' },
155
- { action: 'action_1_name' }
156
- ]
157
- } // the state contains a collection of Action and is completed after any Action has completed and all others have completed via terminateEvents.
158
- ```
159
-
160
- ```js
161
- STATE_NAME : {
162
- sequence: [
163
- { action: 'action_0_name' },
164
- { action: 'action_1_name' }
165
- ]
166
- } // the state contains the Action collection and is completed after all Actions are executed one by one
167
- ```
168
-
169
- terminateEvents - these are events leading to a quick termination of the component's logic.
170
-
171
- ### Event routers ###
172
- Event routers using Urso.observer manage both the state of the entire game and the state of individual components.
173
-
174
- Core implements two event routers:
175
- - Buttons - an event router that manages the state of buttons (see src/js/modules/logic/buttons in the Core repository);
176
- - Sounds - an event router that controls the playback of sounds (see src/js/modules/logic/sounds in the Core repository);
177
-
178
- ### Working with scene objects ###
179
- To work with scene objects (and from the console), you need to use the following tools:
180
- - this.common.find returns false/object/collection (Urso.find('selector') for console access);
181
- - this.common.findOne returns false/object (Urso.findOne('^name') for console access);
182
- - this.common.findAll('.class') returns false/collection (Urso.findAll('.class') for console access);
183
-
184
- The search modifier is the first character of the passed argument.
185
-
186
- The following modifiers are available:
187
- - '^' - Search by name (name);
188
- - '.' - Search by class (class);
189
- - '#' - Search by identifier (id);
239
+ ### 10. Dynamic Scene Object Creation ###
240
+ ----------------------------------
241
+ Objects can be created dynamically (for example, in components).
242
+
243
+ To create an object call Urso.objects.create with object parameters (first argument) and parent object (second argument, optional). If parent is not passed, object is created in root object (world).
244
+
245
+ Example:
246
+ Urso.objects.create(
247
+ {
248
+ type: Urso.types.objects.IMAGE,
249
+ assetKey: assetKey,
250
+ y: 250
251
+ },
252
+ someParentObject
253
+ );
190
254
 
191
- Given that objects can contain other objects, combinations of selectors are also available - Urso.find ('^nameContainer .classText').
255
+ ### 11. Working with Classes and Entities ###
256
+ -------------------------------------
257
+ Class access:
258
+ - this.getInstance('View') — returns object (instance) of View class of the same namespace. That is, for Components.Test.Controller returns object of Components.Test.View class.
259
+ - Urso.getInstance('Modules.Observer.Controller') — returns object (instance) of Observer.Controller class.
260
+ - Urso.getByPath('Modules.Observer.Controller') — returns reference to Observer.Controller class constructor.
192
261
 
193
- The search will search in an object named ^nameContainer for objects with class classText, and at any nesting level.
194
-
195
- ### Dynamically creating scene objects ###
196
- In order to create an object on the scene, you need to call the Urso.objects.create function and pass the desired object parameters to it as the first parameter and the parent object as the second.
262
+ These methods accept parameter path to needed class. Example:
263
+ - Urso.getInstance('Components.Button.Template') — get object of Button.Template class.
264
+ - Urso.getInstance('Components.Button.Template').objects array of objects defined in Template file.
265
+
266
+ Internal calls:
267
+ - In any class you can call this.getInstance('Template') to get Template instance of the same entity.
268
+
269
+ ### 12. Adding Sound and Sound/Event Mapping Configuration ###
270
+ -------------------------------------------------------
271
+ Sounds can be added for any game events: background music, button click sound, etc. Sounds are used as assets added to asset group.
272
+
273
+ Recommended approach — Atlas: set where necessary sounds are in one track; logic launches needed segment by name.
274
+
275
+ Sound logic is located (see src/js/modules/logic/config/sounds in Core repository).
276
+
277
+ Adding sound configuration:
278
+ - Create game file src/app/modules/logic/config/sounds.js.
279
+ - In sounds.js file in getSoundsConfig() method return object where property is group name and value is array of objects with parameters.
280
+
281
+ Record parameters:
282
+ - soundKey: 'backgroundTheme' — access key to sound asset.
283
+ - event: 'sounds.backgroundTheme.play' — event at which sound performs action (for example, playback).
284
+ - action — action: 'play', 'stop', 'pause', 'resume', 'fade'.
285
+ - relaunch: true — allow sound restart.
286
+ - loop: true — looped playback.
287
+
288
+ Action "fade" (volume dynamics):
289
+ - startSound (default false) — starts sound before fade execution.
290
+ - fadeDuration (default 200) — volume change duration.
291
+ - fadeTo (default 1) — final volume (0..1).
292
+
293
+ Example:
294
+ - In button logic create event this.emit('sounds.buttonMenu.play'), and in sounds.js config subscribe this event to needed soundKey/action.
295
+
296
+ { soundKey: 'sound1', event: 'sound1.play.once', action: 'play' },
297
+ { soundKey: 'sound_check', event: 'soundCheck.play.once', action: 'play' },
298
+ { soundKey: 'sound_check', event: 'soundCheck.stop', action: 'stop' },
299
+ { soundKey: 'sound_check', event: 'soundCheck.pause', action: 'pause' },
300
+ { soundKey: 'sound_check', event: 'soundCheck.resume', action: 'resume' },
301
+ { soundKey: 'sound_check', event: 'soundCheck.play.loop', action: 'play', relaunch: true, loop: true }
302
+
303
+ ### 13. LazyLoad Mechanism (Asset Loading Groups) ###
304
+ ----------------------------------------------
305
+ Urso.assets — resource loading logic (see src/js/modules/assets in Core repository).
306
+
307
+ Loading order:
308
+ - All assets without loadingGroup specification are loaded first by _startLoad method and have initial: 0 (see src/js/modules/assets/service in Core repository).
309
+ - Then groups are loaded by _startLazyLoad method by their loadingGroup.
310
+
311
+ Events:
312
+ - Upon group loading completion loader.start launches event Urso.events.MODULES_ASSETS_GROUP_LOADED (see src/js/modules/assets/service).
313
+ - Upon all groups loading completion — event Urso.events.MODULES_ASSETS_LAZYLOAD_FINISHED.
314
+
315
+ Prioritization:
316
+ - Group queue corresponds to order in lazyLoadGroups array (see src/js/modules/assets/config in Core repository).
317
+ - Example: loadingGroup: "lazy" and "afterLazy"; in config this.loadingGroups = { initial: 0, lazy: "lazy", afterLazy: "afterLazy" }, and this.lazyLoadGroups = [ this.loadingGroups.lazy, this.loadingGroups.afterLazy ] — priority "lazy", then "afterLazy".
318
+
319
+ ### 14. States Manager and Components.StateDriven ###
320
+ ----------------------------------------------
321
+ States manager — connection of logical module (Modules.States) controlling active states and their actions, and components inherited from base state-dependent component (Components.StateDriven).
197
322
 
198
- If the parent object is not passed, the object will be created in the root object (world)
323
+ Urso.statesManager manager for working with states (see src/js/modules/statesManager in Core repository).
199
324
 
200
- For example:
201
- ```js
202
- Urso.objects.create(
203
- {
204
- type: Urso.types.objects.IMAGE,
205
- assetKey: assetKey,
206
- y: 250
207
- },
208
- someParentObject
209
- );
210
- ```
325
+ States are launched sequentially after previous one completion. Or, if nextState key is set, then transition occurs to first state that passed guard in this array. Action launches if guard passes, which checks launch possibility.
211
326
 
212
- ### Working with classes and entities ###
213
- To work with classes, the following are used:
214
- - Urso.getInstance ('Modules.Observer.Controller') returns an object (instance) of the Observer.Controller class
215
- - Urso.getPath ('Modules.Observer.Controller') returns a reference to the constructor of the Observer.Controller class
327
+ States and transitions (see src\js\modules\statesManager\configStates.js):
328
+ - State can contain one action completes after its completion.
329
+ - State can contain multiple actions completes by transition rule.
216
330
 
217
- These two methods also support any number of modifiers, which allows more flexibility in applying the desired class in a specific environment.
331
+ Transition types:
332
+ - all — state completes after all actions execution.
333
+ - race — completes after any action completion; others complete through terminate.
334
+ - sequence — completes after all actions execution in order.
218
335
 
219
- For example, if you apply the modifier 'mobile', then Urso.getInstance ('Modules.Observer.Controller') will look for the constructor first in Modules.Observer.Mobile.Controller. If no such constructor is found, then the “default option” Modules.Observer.Controller will be returned;
336
+ Early completion:
337
+ - States can be completed early through terminate (see src\js\modules\statesManager\action.js).
338
+
339
+ configStates fragment:
340
+ STATE_NAME : { action: 'action_name' }
341
+ STATE_NAME : { all: [ { action: 'action_0_name' }, { action: 'action_1_name' } ] }
342
+ STATE_NAME : { race: [ { action: 'action_0_name' }, { action: 'action_1_name' } ] }
343
+ STATE_NAME : { sequence: [ { action: 'action_0_name' }, { action: 'action_1_name' } ] }
220
344
 
221
- Also, any class inside itself can call the following construction this.getInstance ('View'), which will return the desired class of the same entity, in our case it is a View instance
345
+ Components.StateDriven (see src/js/components/stateDriven):
346
+ - Has configStates — state entry checks (guard).
347
+ - Has configActions — actions for launch.
348
+ - Component implementation is made using _subscribeOnce method, so when inheriting from it, make sure to use super._subscribeOnce() call in your own _subscribeOnce method.
349
+
350
+ Component code example:
351
+ configStates = {
352
+
353
+ SHOW_MENU: {
354
+ guard: () => { return Urso.localData.get('states.allow.SHOW_MENU') },
355
+ },
356
+ };
357
+
358
+ configActions = {
359
+
360
+ menuOpenAction: {
361
+ guard: () => { return Urso.localData.get('spaceKey.input.blocked') }, // check if buttons are blocked
362
+ run: (finishCallback) => { this._changeVisibility(true), finishCallback() }, // execute if guard returned true
363
+ },
364
+
365
+ menuCloseMouseAction: {
366
+ run: (finishCallback) => { this._changeVisibility(false), finishCallback() }
367
+ terminate: () => { log('closed by menu button on screen') }, // output information how menu was closed.
368
+ },
369
+
370
+ menuCloseEscAction: {
371
+ run: (finishCallback) => { this._changeVisibility(false), finishCallback() }
372
+ terminate: () => { log('closed by Esc key on keyboard') }, // output information how menu was closed.
373
+ },
374
+ };
375
+
376
+ - SHOW_MENU state: actions — menuOpenAction (open), menuCloseEscAction (close by Esc), menuCloseButtonAction (close by button).
377
+ - After closing — transition nextState: ['WAIT'].
378
+ - In component controller state entry check (SHOW_MENU) through configStates; in configActions — open/close logic.
379
+
380
+ ### 15. LayersSwitcher Component ###
381
+ ----------------------------
382
+ Component for enabling and disabling layers in game (see urso\core\src\js\components\layersSwitcher).
383
+
384
+ Files:
385
+ - config.js — layer list and selectors for control.
386
+ - controller.js — component logic.
387
+
388
+ Subscription:
389
+ - controller.js is subscribed to event Urso.events.COMPONENTS_LAYERS_SWITCHER_SWITCH with parameter 'groupName' — name of enabled layer selector set.
390
+
391
+ Behavior:
392
+ - When event triggers, component makes all layers from managed layers list invisible and leaves only selected layer objects visible.
393
+
394
+ Configuration:
395
+ - this.allLayers[] — list of selectors of all managed objects.
396
+ - this.groupsLayers{} — enabled layer dependencies: key — group name; value — selector array.
397
+
398
+ this.groupsLayers example:
399
+ {
400
+ 'mainElements': ['^logo', '^mainButton', '.baseGame'],
401
+ 'background': ['.background'],
402
+ }
403
+
404
+ ### 16. Modifications and Mixins ###
405
+ -----------------------------
406
+ Modifications — code files executed instead of standard ones under certain condition.
407
+
408
+ Example of modifications connection in component info file:
409
+ Controller: require('./controller.js'),
410
+ Template: require('./template.js'),
411
+ modifications: { Desktop: { Controller: require('./modifications/desktop/controller.js') } }
412
+
413
+ If Urso.getInstancesModes() contains Desktop, controller from modifications/desktop/controller.js will be loaded. Otherwise — standard Controller.
414
+
415
+ Mixins — methods for reuse in different unrelated classes.
416
+
417
+ Mixin connection (similar to modifications):
418
+ mixins: { Desktop: { Controller: require('./mixins/desktop/controller.js') } }
419
+
420
+ If Urso.getInstancesModes() contains Desktop — method from mixin ('./mixins/desktop/controller.js') will execute in component Controller.
421
+
422
+ ### 17. Transitions for Objects ###
423
+ ----------------------------
424
+ Transition — smooth transformation (see src\js\modules\objects\baseModel.js in Core repository).
425
+
426
+ Parameters:
427
+ - transitionDelay — delay (ms) before transition start (optional).
428
+ - transitionDuration — transition duration.
429
+ - transitionProperty — list of keys whose change initiates transition.
430
+
431
+ Example:
432
+ transitionDelay: 1000
433
+ transitionDuration: 2000
434
+ transitionProperty: "alpha x y"
435
+
436
+ Changing:
437
+ - object.alpha = 1 (appearance) or 0 (disappearance).
438
+ - object.x = 200; object.y = 300 (diagonal movement).
439
+ You can set one coordinate for axis movement.
440
+
441
+ ### 18. Game Text Localization ###
442
+ ---------------------------
443
+ Text translation to different languages is performed through JSON localization files for each language. Structure: translation key — text.
444
+
445
+ Example:
446
+ "RULES_HEADER": "First Level",
447
+ "RULES": "Rules",
448
+ "MY_BET_ITEM_TIME": "Time",
449
+ "Bet": "Bet"
450
+
451
+ Usage:
452
+ - In text object add localeId parameter with translation key. In this case localization will be pulled automatically.
453
+ - Connect json localization file in assets.
454
+ - Execute command Urso.core.i18n.setLocale(localeKey), where localeKey — json localization file name.
455
+
456
+ 18.2. Code Usage
457
+ - Urso.i18n.get(localeId, localeVariables?)
458
+ - Urso.i18n.setLocale(localeKey)
459
+ - Urso.i18n.loadAndSetLocale(localeKey, pathToLocaleJson)
460
+
461
+ 18.3. UI Auto-update
462
+ - Use localeId instead of text in text objects
463
+ - Listen to language change event (Urso.events.MODULES_I18N_NEW_LOCALE_WAS_SET) and update texts
464
+
465
+ ### 19. Transport ###
466
+ -------------
467
+ 19.1. Connection Type Support
468
+ - websocket, xhr (by configuration)
469
+
470
+ 19.2. Configuration
471
+ - useTransport: true/false (ConfigMain)
472
+ - autoReconnect: boolean,
473
+ - reconnectTimeout: number in ms,
474
+ - type: websocket | xhr
475
+ - host: string
476
+
477
+ 19.3. ModulesTransportDecorator Decorator
478
+ - toServer/toFront
479
+
480
+ ### 20. Additional Reference Sections ###
481
+
482
+ 20.1. Core Modules (Lib)
483
+ - helper — utilities (for example, parseGetParams, waitForDomElement, arraysGetUniqElements, replaceAll, recursiveGet, mergeObjectsRecursive).
484
+ - cache — get/has/set/remove/clear.
485
+ - device — device data (isMobile/tablet/desktop; getScreenSize/Width/Height; getOrientation; getPixelRatio).
486
+ - loader — PIXI.Loader overlay: add(key,url), load(cb), onProgress.add(cb).
487
+ - localData — local key-value storage.
488
+ - logger — logging levels: ERROR, WARNING, INFO, LOG (level is set in configuration and can be overridden through URL parameter).
489
+ - math, time, tween, objectPool, composition — service utilities/infrastructure.
490
+
491
+ 20.2. Additional Information about Templates and Scenes
492
+ - Template consists of styles, resource list (assets) and object tree (objects).
493
+ - Control methods are available for scenes, including scene switching, FPS getting, pause/resume.
494
+
495
+ 20.3. Practical Recommendations, Debugging, Profiling
496
+ - For event work clear domain naming is recommended: ui.*, game.*, modules.*, components.*.
497
+ - For assets — grouping and lazyLoad; for weak devices — FPS limitation (config.fps.limit) and optimizeLowPerformance mode.
498
+ - For sound consider tab visibility rules (browser event handling).
499
+ - Debug component — for FPS/metrics monitoring
500
+
501
+ ### 21. Extra (BrowserEvents, PixiPatch) ###
502
+ ------------------------------------
503
+ 21.1. BrowserEvents
504
+ - Browser event translation (resize, visibilitychange, input) to engine events: EXTRA_BROWSEREVENTS_*
505
+ - Provides scene/sound/render reaction
506
+
507
+ 21.2. PixiPatch
508
+ - PIXI fixes/extensions
509
+
510
+ ### 22. Types (Urso.types) ###
511
+ ----------------------
512
+ 22.1. assets
513
+ - ATLAS, AUDIOSPRITE, BITMAPFONT, CONTAINER, FONT, IMAGE, JSON, JSONATLAS, SOUND, SPINE, HTML
514
+
515
+ 22.2. objects
516
+ Object types (Urso.types.objects)
517
+ - ATLASIMAGE, BITMAPTEXT, BUTTON, BUTTONCOMPOSITE, CHECKBOX, COLLECTION, COMPONENT, CONTAINER, DRAGCONTAINER, EMITTER, EMITTERFX, GRAPHICS, GROUP, HITAREA, IMAGE, IMAGESANIMATION, MASK, NINESLICEPLANE, SCROLLBOX, SLIDER, SPINE, TEXT, TEXTINPUT, TOGGLE, WORLD
518
+
519
+ Creation
520
+ - Urso.objects.create(params, parent?)
521
+
522
+ Example:
523
+ Urso.objects.create({
524
+ type: Urso.types.objects.IMAGE,
525
+ assetKey: 'logo',
526
+ x: 100, y: 100, name: 'logo'
527
+ }, someParent);
528
+
529
+ Search
530
+ - this.common.find / findOne / findAll
531
+ - Urso.find / findOne / findAll (console)
532
+ - Selectors: ^name, .class, #id; combined: '^container .className'
533
+
534
+ Base model properties (ModulesObjectsBaseModel)
535
+ - Position, scale, anchors, visibility, alpha, angle, sizes, classes/identifiers (can be found in setupParams)
536
+
537
+ Specific object model properties contain all base model properties as well as their own properties, which can be found in model setupParams.
538
+
539
+ Specialized objects
540
+ - Button/Toggle/Checkbox/Slider — interactive; Scrollbox — scrolling; Spine — animation; Emitter — particles; NineSlicePlane — adaptive panels; Text/TextInput/BitmapText — text
541
+
542
+ 22.3. Other Enumerations
543
+ - Screen orientations: Urso.device.ScreenOrientation.LANDSCAPE/ PORTRAIT
544
+ - Engine constants
545
+
546
+ ### 23. Events (Urso.events) ###
547
+ ------------------------
548
+ 23.1. System Event Examples
549
+ - MODULES_SCENES_NEW_SCENE_INIT
550
+ - EXTRA_BROWSEREVENTS_WINDOW_RESIZE
551
+ - MODULES_ASSETS_LOAD_PROGRESS
552
+
553
+ 23.2. Naming Conventions
554
+ - module.domain.action
555
+ - ui.*, game.*, sound.*, scenes.*, assets.*, transport.*
556
+
557
+ ### 24. Practical Patterns and Recommendations ###
558
+ -------------------------------------------
559
+ 24.1. Abstraction Layers
560
+ - Logic — in services/routers
561
+ - Presentation — in View and templates
562
+ - Controller — only API/subscriptions
563
+
564
+ 24.2. Selectors
565
+ - Use ^, #, . and combinations
566
+ - Don't overload search — cache references to frequently used objects
567
+
568
+ 24.3. Events
569
+ - Minimize global subscriptions
570
+ - Remove subscriptions on destruction
571
+
572
+ 24.4. Performance
573
+ - Group resources
574
+ - Tune fps and quality
575
+ - Use audiosprites and atlases
576
+ - Disable invisible containers
577
+
578
+ 24.5. Asset Organization
579
+ - Coordinate keys and paths
580
+ - Include webp when supported
581
+ - Control name intersections in atlases
582
+
583
+ 24.6. Sound
584
+ - Keep sound and event mapping config centralized
585
+
586
+ 24.7. States
587
+ - Break complex states into all/race/sequence combinations
588
+ - Use terminateEvents for graceful parallel Action stopping
589
+
590
+ ### 25. Optimization and Debugging ###
591
+ -------------------------------
592
+ 25.1. Debug Component
593
+ - FPS display, draw calls, object count
594
+ - Coordinate switcher
595
+
596
+ 25.2. Profiling
597
+ - scenes.getFps(), getFpsData()
598
+ - Logger with levels
599
+ - Custom profiler when needed
600
+
601
+ 25.3. Memory and Cache
602
+ - Watch large textures/sprites
603
+ - Use LibObjectPool for object reuse
604
+
605
+ 25.4. Build
606
+ - Debug build:dev; minimize build:prod
607
+
608
+ ### 26. FAQ ###
609
+ -------
610
+ - How to launch game? — see Quick Start: index.js + load.js + runGame
611
+ - Where to connect modules? — config/load.js
612
+ - How to add scene? — create template and register scene in Template/Scenes
613
+ - How to play sound on event? — add record in modules/logic/config/sounds.js and emit event
614
+ - How to find object? — this.common.find/One/All or Urso.find*/ selectors ^ . #
615
+ - How to configure asset quality? — through Urso.assets.updateQuality/ setQuality and qualityFactors config
616
+
617
+ ### 27. Examples from A to Z ###
618
+ ------------------------
619
+ 27.1. Mini-menu + game transition
620
+ - main.js: defaultScene = 'menu'
621
+ - load.js: require('./scenes/menu'); require('./scenes/game');
622
+ - In Menu template: PLAY button calls Urso.scenes.display('game')
623
+
624
+ 27.2. Dynamic object creation
625
+ Urso.objects.create({ type: Urso.types.objects.TEXT, text: 'Hello', x: 100, y: 100 });
626
+
627
+ 27.3. Selectors
628
+ Urso.find('^container .className'); Urso.findOne('#uniqueId'); Urso.findAll('.buttonClass');
629
+
630
+ 27.4. Events
631
+ this.addListener('game.start', handler); this.emit('game.start', { level: 1 });
632
+
633
+ 27.5. States
634
+ STATE: { sequence: [ { action: 'a0' }, { action: 'a1' } ] }
635
+
636
+ 27.6. Sound on event
637
+ sounds.js: { soundKey: 'sfxClick', event: 'ui.click', action: 'play' }
638
+ emit: this.emit('ui.click')
639
+
640
+ 27.7. Lazy asset loading
641
+ - Add group to lazyLoadGroups
642
+ - When needed call loading from logic/component
643
+
644
+ 27.8. Fullscreen mode
645
+ emit('fullscreen.toggle')
646
+
647
+ 27.9. Debug
648
+ Add Debug component to scene for monitoring
649
+
650
+ ### 28. API Reference ###
651
+ -----------------
652
+ 28.1. Core/Global
653
+ - Urso.runGame()
654
+ - Urso.getInstance(path, ...modifiers)
655
+ - Urso.getByPath(path, ...modifiers)
656
+ - Urso.find / findOne / findAll
657
+
658
+ 28.2. Observer
659
+ - addListener(name, cb, isGlobal?)
660
+ - removeListener(name, cb, isGlobal?)
661
+ - emit(name, params?, delay?)
662
+
663
+ 28.3. Assets/Loader/Cache
664
+ - assets.preload(assets, onComplete, onProgress?, onError?)
665
+ - assets.loadGroup(groupName, onComplete, onProgress?, onError?)
666
+ - loader.add(key, url); loader.load(cb); loader.onProgress.add(cb)
667
+ - cache.get/has/set/remove/clear
668
+
669
+ 28.4. Objects
670
+ - objects.create(params, parent?)
671
+ - Model properties: position, scale, anchor, visibility, etc.
672
+
673
+ 28.5. Scenes
674
+ - scenes.display(name), getFps(), getFpsData(), pause(), resume()
675
+
676
+ 28.6. I18n
677
+ - Urso.i18n.get(localeId, localeVariables?)
678
+ - Urso.i18n.setLocale(localeKey)
679
+ - Urso.i18n.loadAndSetLocale(localeKey, pathToLocaleJson)
680
+
681
+ 28.7. Device
682
+ - isMobile/tablet/desktop/touch
683
+ - getScreenWidth/Height(), getOrientation(), getPixelRatio()
684
+
685
+ 28.8. Logger
686
+ - error/warning/info/log; levels through defaultLogLevel
687
+
688
+ ### 29. Appendices ###
689
+ --------------
690
+ 29.1. Naming Conventions
691
+ - Event names: domain.action.detail (for example, sound.play.click, ui.button.play.click)
692
+ - Object names: clear and unique for findOne '^name'
693
+ - Object classes: '.class-name' reflects role/style
694
+
695
+ 29.2. Release Checklist
696
+ - Loading groups and lazyLoad checked
697
+ - Asset quality chosen for devices
698
+ - Sound config matches actual assets
699
+ - Logs and levels reduced for production
700
+ - Performance on target devices measured
701
+
702
+ ### 30. Code Examples ###
703
+ -----------------
704
+ index.js
705
+
706
+ require("@urso/core");
707
+ require("./app/config/load");
708
+ window.onload = Urso.runGame;
709
+
710
+ config/main.js
711
+ //overriding core config
712
+ Urso.config.extendingChain = ['Urso.Core', 'Urso.App'];
713
+ Urso.config.title = 'SomeGame';
714
+ Urso.config.appVersion = '1.11.10'; //game anticache get param
715
+ Urso.config.defaultScene = 'play'; //default game scene for urso engine
716
+
717
+ config/load.js
718
+
719
+ window.Urso.App = {
720
+ Components: {
721
+ Bg: {
722
+ Controller: require('./../components/bg/controller.js'),
723
+ Template: require('./../components/bg/template.js'),
724
+ },
725
+ Intro: {
726
+ Controller: require('./../components/intro/controller.js'),
727
+ Template: require('./../components/intro/template.js'),
728
+ },
729
+ LayersSwitcher: {
730
+ Config: require('./../components/layersSwitcher/config.js') //config for core LayersSwitcher component
731
+ },
732
+ SoundsInit: {
733
+ Controller: require('./../components/soundsInit/controller.js'),
734
+ },
735
+ },
736
+ Modules: {
737
+ I18n: {
738
+ Config: require('./../modules/i18n/config.js')
739
+ },
740
+ Logic: {
741
+ Controller: require('./../modules/logic/controller'),
742
+ Main: require('./../modules/logic/main'),
743
+ Config: {
744
+ Sounds: require('./../modules/logic/config/sounds.js') //sounds router
745
+ }
746
+ },
747
+ Observer: {
748
+ Events: require('../modules/observer/events') //custom events config
749
+ },
750
+ Scenes: {
751
+ ResolutionsConfig: require('./../modules/scenes/resolutionsConfig.js'),
752
+ }
753
+ },
754
+ Templates: {
755
+ Scenes: {
756
+ Play: require('./../templates/scenes/play.js')
757
+ },
758
+ Groups: {
759
+ AtlasLoadGroup: require('./../templates/groups/atlasLoadGroup.js'),
760
+ RestAssetsLoadGroup: require('./../templates/groups/restAssetsLoadGroup.js'),
761
+ }
762
+ },
763
+ };
764
+
765
+ require('./main.js');
766
+
767
+ ### 31. Links ###
768
+ ---------
769
+ - https://ursojs.io/examples.html
770
+ - https://github.com/megbrimef/urso-examples
771
+ - https://github.com/megbrimef/urso
772
+ - https://github.com/megbrimef/urso-slot-base
773
+ - https://discord.gg/JauD9CbDHA
222
774
 
223
775
 
224
776
  ### License ###