/
sphere2-core-api.txt
1922 lines (1317 loc) · 67.5 KB
/
sphere2-core-api.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
Sphere v2 Core API Reference
============================
As the successor to the original Sphere engine, miniSphere implements nearly
the entire Sphere v1 API. However, the v1 API is quite dated and, as of
miniSphere 4.0, has been deprecated in its entirety. It is not documented here
at all; while games using the legacy functions will continue to run, new code
should be written against the modern Sphere v2 API, documented here.
In order to ease migration of existing Sphere v1 codebases to Sphere v2, legacy
and modern API calls may be freely intermingled within the same codebase, and
that holds true even when the engine is running in compatibility mode.
JSON Game Manifest (`game.json`)
--------------------------------
To take full advantage of the Sphere v2 platform, a game package must include a
file named `game.json` in its root directory. This file holds metadata such as
the title and author, as well as some control information which affects how the
engine runs the game.
Here's a sample manifest:
{
"name": "Spectacles: Bruce's Story",
"version": 2,
"apiLevel": 1,
"saveID": "fatCerberus.spectacles",
"author": "Fat Cerberus",
"summary": "Follow Scott Starcross in his quest to stop the Primus.",
"resolution": "320x240",
"main": "@/bin/main.mjs"
}
JSON fields defined by the Sphere v2 specification are documented below.
Because the manifest format is JSON, as many additional fields may be added as
needed, and their values can be accessed from JavaScript through `Sphere.Game`.
"version" [default: 2]
The Sphere standards version the game was developed against. If this is
set to 2 (or is just not present) the game runs in Sphere v2 mode. In
Sphere v2 mode, the main script is run as a module, either CommonJS or
mJS depending on the file extension.
If this is set to 1, the game runs in Sphere 1.x compatibility mode. In
compatibility mode, the main module is executed as top-level program code,
and miniSphere calls the global `game()` function--if one is provided--to
begin game execution.
Note: Regardless of the version specified, both Sphere v1 and v2 APIs will
be available for use by game code. The standards version merely
tells the engine how to load the main module.
"apiLevel" [default: 1]
The minimum API level required to run the game.
"author" [default: none]
The name of the person or company who developed the game.
"fullScreen" [default: false]
The game's preferred fullscreen mode. If the engine is started without
passing either `--windowed` or `--fullscreen` on the command line, the
value of this property will decide whether to start in fullscreen mode or
not.
"main" [required]
The SphereFS path of the main JavaScript module (see below for more on
SphereFS). This is the script miniSphere will run when the game is
started. If no "main" field is present, the game will not start.
"name" [default: "Untitled"]
The title of the game. This field must be present; if it is not, the game
will not start.
"resolution" [required]
The default screen resolution of the game, expressed as a string of the
form "WxH", specifying the number of pixels across and down. For example,
720p resolution would be expressed as "1280x720".
Note: The resolution can be changed at runtime by calling screen.resize().
"sandbox" [default: "full"]
Specifies the SphereFS sandbox enforcement mode. This should have one of
the following values:
"full": Full enforcement. This is the default. Using an absolute
path is illegal and will throw an error, and all files and
directories except for those in `~/` (the game's save data
directory) are treated as read-only.
"relaxed": Allow read-only access to files named by an absolute path
and enable full write access to `@/`. This is useful during
development but not recommended for production, particulary
as your game may end up installed in a read-only location.
"none": NOT RECOMMENDED! This disables the sandbox entirely and allows
write access to all files, including those named by an absolute
path and everything under `#/`. Unless you know what you're
doing (and maybe even then), avoid this mode at all costs!
"saveID" [default: none]
A string usually of the form "authorID.titleID" uniquely identifying the
game for the purposes of save data management.
Note: While providing a save ID is optional, one must be defined before a
game can use its SphereFS save store (`~/`). Legacy games using
only an SGM manifest therefore can't take advantage of the save
store.
"summary" [default: none]
A short summary of the game. While there is no imposed length limit, it
is recommended to keep this short (150 characters or less) with no line
breaks.
SphereFS File System
--------------------
Sphere uses the SphereFS standard to interpret file paths. Under SphereFS,
when a relative path is used in an API call, it will be resolved relative to
the root of the game package (where `game.json` is located). To load files
from a different location, you can use one of the SphereFS prefixes:
@/: The root of the game's sandboxed file system. Usually redundant, but
can be useful to qualify filenames in situations where a bare SphereFS
filename will be ambiguous, for example in an `import` declaration.
This directory is read-only; trying to save or modify anything here
will cause a TypeError to be thrown.
$/: The directory containing the startup script. This is mostly provided
as a convenience for specifying module names in `import` declarations.
#/: The engine's system directory. This contains assets included with the
engine. As with `@/`, this is read-only to Sphere games.
~/: The current user's save data directory (note: requires a save ID; refer
to the section on `game.json` above). This is generally used to store
save data and such where the user can easily access it.
As an example, the following will create a FileStream which allows reading from
the file `EatyPig.bin` residing in the user's save data directory.
let file = new FileStream('~/EatyPig.bin', FileOp.Read);
Note: Absolute paths are forbidden, and any attempt to circumvent the sandbox
to break into the underlying file system, e.g. "@/../maggie.fat", will
be met with a sandbox violation error.
The Sphere Event Loop
---------------------
Sphere, like most JavaScript-based platforms, is built around the concept of a
central event loop that keeps the engine running and schedules JavaScript
execution. JavaScript operations cannot run indefinitely; the engine runs in
a single thread, so the game must yield to the event loop periodically to allow
other tasks to run. There are two ways this can be done: either by allowing
the current operation to run to completion, or by suspending execution using
the `await` operator.
The event loop begins running after all JavaScript modules have been loaded and
remains active as long as there is something for it to do. Each iteration of
the event loop represents one frame and consists of three phases:
Render: The Render phase calls jobs set up with `Dispatch.onRender()`.
This phase is unique in that it may be skipped entirely in order
to maintain the game's desired frame rate. Only drawing operations
should be performed during this phase. Immediately after the
Render phase, the contents of the backbuffer are flipped to the
screen and the backbuffer is cleared.
Update: The Update phase calls jobs set up with `Dispatch.onUpdate()`.
Updates are regulated by `Sphere.frameRate` (see below), which you
can take advantage of to simplify, e.g., animation code.
Dispatch: The Dispatch phase is a multi-purpose phase which calls one-off
jobs such as `Dispatch.now()` and settles promises. The Dispatch
phase runs until there are no more jobs to execute, ensuring
results which are available immediately aren't delayed until the
next frame.
`Sphere` Namespace
------------------
The `Sphere` namespace hosts functions and properties that allow the game to
communicate with the underlying Sphere platform. The properties provide access
to the engine's name, version number, and API level, and there are several
methods for managing execution.
Sphere.Engine [read-only]
A string specifying the name and version number of the game engine. The
version number takes the form X.Y.Z, where X is the major version, Y is the
minor version, and Z is the patch level.
Sphere.Version [read-only]
Sphere.APILevel [read-only]
The Sphere API version and level supported by the engine, respectively.
`Version` indicates which version of the Sphere API is supported (e.g., 2),
while `APILevel` reflects the evolutionary stage. Whenever new classes,
methods, or properties are added to the Core API, the API level is
increased.
Sphere.Compiler [read-only]
A string specifying the name and version number of the compiler or build
tool used to make the game distribution. If no compiler information is
available for the current game, this evaluates to `undefined`.
Sphere.Game [non-replaceable]
An object whose properties describe the currently running game. The object
consists of everything in the JSON manifest plus any fields synthesized by
the engine.
Sphere.frameRate [read/write]
Gets or sets the frame rate. Set this to Infinity to disable the frame
limiter. The default is 60 FPS.
The frame rate is used to regulate the event loop. For example if this is
set to 60 (the default), the event loop will perform 60 iterations per
second, skipping renders as necessary to meet that goal.
Sphere.frameSkip [read/write]
Gets or sets the maximum number of frames the engine is allowed to skip in
order to maintain the desired frame rate.
Sphere.fullScreen [read/write]
Gets or sets whether the engine is running in fullscreen mode. Set this to
`true` for fullscreen, or `false` for windowed.
Note: If an SSj debugger instance is attached, the engine is forced into
windowed mode and any change to the value of `screen.fullScreen` will
be silently ignored.
Sphere.abort(message);
Aborts execution. This is effectively a forced crash: JavaScript execution
will cease immediately, and the exception screen will be shown displaying
`message`.
Note: Sphere.abort() bypasses all exception handling mechanisms, including
the debugger if it's attached. Be sure you know what you're doing!
Sphere.now();
Returns the number of frames (including skipped frames) processed by the
engine since it started running. To measure wall clock time instead, use
`Date.now()`.
Note: This value will wrap around to zero after around 4.3 billion frames.
That typically isn't an issue: at 60 FPS, a game would need to run
continuously for *over 2 years* before the timer would roll over.
Sphere.restart();
Restarts the engine. All in-flight Dispatch jobs are canceled so that once
control returns to the event loop, the engine will initiate a restart.
Note: This initiates an asynchronous shutdown. The game will restart ONLY
after control has returned to the event loop. Note that dispatching
new update or render jobs before then will cancel the request!
Sphere.setResolution(width, height);
Changes the game's resolution. This determines the width and height of
the backbuffer (see `Surface.Screen` below); higher resolutions allow you
to render more detail.
Note: This change is not persistent and lasts only until the engine is
closed.
Sphere.shutDown();
Shuts down the engine. All in-flight Dispatch jobs are canceled so that
once control returns to the event loop, the engine will close.
Note: This initiates an asynchronous shutdown. The engine will close ONLY
after control has returned to the event loop. Note that dispatching
new update or render jobs before then will cancel the request!
Sphere.sleep(frames);
Returns a promise which resolves after the specified number of frames have
elapsed. Can be used with `await`. This is useful to delay execution of a
function without blocking the event loop.
`Color` Object
--------------
The `Color` object represents an RGB color value. It also has an alpha
component and can therefore represent translucent colors.
Color.Red [read-only]
Color.Green [read-only]
Color.Blue [read-only]
Color.Transparent [read-only]
etc...
Gets a copy of a predefined color. The entire X11 color set is provided,
giving you access to such colors as `DodgerBlue` and `Chartreuse` in
addition to the standard red, green, blue, yellow, etc.
Each of these is an accessor which returns a new Color object every time
it is invoked. This ensures that code like what's shown below won't cause
undesirable side effects:
let customColor = Color.Red;
customColor.blue = 255; // we needed magenta instead
The downside to this is that e.g. `Color.Red === Color.Red` evaluates to
false, but this is rarely an issue in practice.
Color.is(color1, color2);
Returns true if `color1` refers to the same physical color as `color2`
without regard to their alpha components. Otherwise returns false.
Note: This is not the same as comparing the color objects' .name properties
because Color#name encodes the alpha channel in addition to the
physical color.
Color.mix(color1, color2[, w1, w2]);
Calculates a weighted average of two colors. `w1` and `w2` are optional
and specify the relative weights of `color1` and `color2` respectively. If
the weights are omitted, the mix is 50/50.
Color.of(name);
Returns a Color object from `name`, which can either be the name of a
predefined X11 color without spaces (e.g. "chartreuse"), or an ARGB
signature such as "#800000FF". If `name` cannot be resolved to a color,
throws a TypeError.
new Color(red, green, blue[, alpha]);
Constructs a new Color object. Color objects are used to specify the color
of elements such as vertices and primitives. Color components should be in
the range [0.0,1.0]; out-of-range values are silently clamped. `alpha`
specifies the color's opacity and defaults to 1.0 if not provided.
Color#r [read/write]
Color#g [read/write]
Color#b [read/write]
Color#a [read/write]
Gets or sets the individual components of the color (red, green, blue, or
alpha). Range is [0.0,1.0]; while values outside this range are accepted,
HDR is not supported and the engine will automatically clamp such colors
when rendered.
Color#name [read-only]
Gets the name of the Color according to its component values such that
Color.of(color.name) will give back a Color with the same values. Useful
for saving and reading back colors from save files.
Color#clone();
Returns a copy of this Color object. Changes to the clone will not affect
the original object.
Color#fadeTo(alpha_factor);
Scales this color's alpha channel by `alpha_factor`, between 0.0 and 1.0,
and returns the result. The red, green, and blue components are not
modified. One use for this is when you need to make a predefined color
translucent; for example:
let translucentBlue = Color.Blue.fadeTo(0.5);
`DirectoryStream` Object
------------------------
The `DirectoryStream` object allows you to read the contents of a directory.
This works a lot like reading data from a `FileStream` (see below) in that you
read directory entries one at a time. `DirectoryStream` also implements the
JavaScript ES6 iterator protocol, so you can use it in a `from()` query or
`for...of` loop.
new DirectoryStream(dir_name);
Constructs a new DirectoryStream which reads entries from `dir_name`. If
the directory named by `dir_name` doesn't exist, throws an error.
DirectoryStream#fileCount [read-only]
Gets the number of entries (both files and directories) in the directory
listing.
DirectoryStream#fileName [read-only]
Gets the full SphereFS pathname of the directory whose entries are being
enumerated.
Note: Under SphereFS canonicalization rules, the pathname of a directory
always ends in a slash (`/`).
DirectoryStream#position [read/write]
Gets or sets the position within the stream. This is an index into the
directory specifying which entry will be read next.
DirectoryStream#dispose();
Disposes of the DirectoryStream object, closing the underlying directory.
Attempting to the object afterwards will throw an error.
Note: While it's not strictly necessary to call `dispose()` on stream
objects, it may take some time for the garbage collector to get to
them. If there's an active DirectoryStream for a given directory, an
error may be thrown if you try to construct another one.
DirectoryStream#next();
Reads the next entry from the directory and advances the stream position.
This returns an object. If there are no entries remaining, the object's
`done` property is set to `true`; otherwise, `done` is `false` and `value`
is an object with the following properties:
value.isDirectory
`true` if the entry is for a subdirectory, otherwise `false`.
value.fileName
The file or directory name of the entry. Directory names always
end in a slash (`/`).
value.fullPath
The full SphereFS pathname of the entry. As with `value.fileName`,
directory paths end in a slash (`/`) per SphereFS canonicalization
rules.
Note: This method is compatible with the JavaScript ES6 iterator protocol,
allowing you to use the DirectoryStream as input to a `from()` query.
Refer to the Sphere Runtime API documentation for more information
about `from()`.
DirectoryStream#rewind();
Rewinds the stream and resets the position to 0. If the directory contents
have changed, rewinding the DirectoryStream will allow you to enumerate the
new entries without creating a new stream.
`Dispatch` Namespace
--------------------
The Dispatch API is used to set up asynchronous function calls which are later
performed from a designated part of the Sphere event loop. This is like an
advanced version of Sphere v1's update and render scripts, but more tightly
integrated and available throughout the engine.
When queueing a job, a token is returned which allows you to manage the
in-flight job. See the documentation for `JobToken` below to find out what you
can do with the token.
Dispatch.cancelAll();
Cancels all one-time jobs (except `onExit`) in the job queue. In order to
prevent mishaps, this does not cancel update, render and exit jobs. Those
must be cancelled individually.
Dispatch.later(num_frames, callback);
Sets up a one-time job to call `callback` from the event loop after
`num_frames` frames have passed.
Returns a `JobToken` you can use the manage the job.
Dispatch.now(callback);
Sets up a one-time job to call `callback` from the event loop during the
current frame. This is useful for performing operations that need to be
done from the event loop with minimal delay.
Returns a `JobToken` you can use to manage the job.
Note: Dispatch.now(fn) is *NOT* an alias for Dispatch.later(0, fn). The
latter runs at the beginning of the next frame; Dispatch.now() jobs
always run during the same frame they were issued.
Dispatch.onExit(callback);
Sets up a one-time job to call `callback` after the event loop exits. This
is useful when you need to ensure something always runs before the engine
terminates; for example, automatically saving the game or finalizing a log
file.
Returns a `JobToken` you can use to manage the job.
Note: Try not to do anything too intensive in an `onExit()` job if you can
avoid it; the engine won't close until all exit jobs have finished
running, so excessive delays here are likely to frustrate the user.
Dispatch.onRender(fn[, options]);
Dispatch.onUpdate(fn[, options]);
Sets up a recurring job to call `fn` during a specified event loop phase.
For example, `onRender()` jobs are called before the backbuffer is flipped,
and `onUpdate()` jobs are called at the start of each frame.
Returns a `JobToken` you can use to manage the job.
options.inBackground [default: false]
If this is `true`, the job won't keep the event loop alive. This is
useful for screen overlays and the like that you want to run in the
background without preventing the game from exiting.
options.priority [default: 0.0]
Determines the order of calls when there is more than one job. Render
jobs are performed in ascending priority order, while update jobs are
performed in descending priority order. The priority can be negative,
and fractional priorities are honored: 8.12, for example, is considered
a higher priority than 8.0.
`FS` Namespace
--------------
The `FS` namespace allows your game to access asset and save files, create or
remove directories, etc. All file system operations are sandboxed to prevent
damage to the system.
FS.createDirectory(dir_name);
Creates a directory and any of its parent directories that don't already
exist. If the directory already exists, this function does nothing.
Note: As indicated above, `FS.createDirectory()` is safe to call even if
the specified directory already exists; no error will be thrown in
that case. This allows you to call it to ensure a directory exists
before you access it, without needing an explicit check beforehand.
FS.deleteFile(filename);
Deletes `filename` from the file system.
FS.directoryExists(dir_name);
Checks whether the specified directory exists and returns true if it does.
Otherwise, returns false.
FS.evaluateScript(filename);
Executes a JavaScript file in the global scope and returns the result.
This is useful for executing scripts originally written for the Web, where
modules are not supported.
Note: Depending on the particular script being evaluated, this function
can--and likely will--create new global functions and variables. Be
sure you know what you're doing!
FS.fileExists(filename);
Checks whether the specified file exists and returns true if it does.
Otherwise, returns false.
FS.fullPath(filename[, base_dir]);
Resolves a filename (which may contain relative path components, or even be
relative itself) to its full, canonical SphereFS pathname. `base_dir` is
optional and specifies a base directory for relative paths. The file or
directory ultimately referred to doesn't need to exist.
If `fileName` begins with a SphereFS prefix, it's resolved normally,
without regard to `base_dir`. Otherwise, `fileName` is considered to be
relative to `base_dir`.
FS.readFile(filename);
Reads an entire UTF-8 text file into a JavaScript string. This is a
convenience to avoid the need to explicitly construct a FileStream and
decode the file contents when all you want is to load a text file.
Note: This performs UTF-8 decoding, making it unsuitable for use with
binary data. To work with binary files, use a FileStream object
instead.
FS.relativePath(filename, base_dir);
Abbreviates a full SphereFS pathname by returning its path relative to
`base_dir`. This can be useful when logging filenames or displaying track
names, for example.
FS.removeDirectory(dir_name);
Deletes the specified directory. The directory must be empty or an error
will be thrown.
FS.rename(orig_name, new_name);
Renames the file named by `orig_name` to `new_name`, both of which are
assumed to be full paths. This can also be used to move a file between
directories; if so, the destination directory must already exist.
FS.writeFile(filename, string);
Writes a string out to a UTF-8 text file. If a file already exists with
the specified filename, it will be overwritten.
Note: This performs UTF-8 encoding, making it unsuitable for use with
binary data. To work with binary files, use a FileStream object
instead.
`FileStream` Object
-------------------
new FileStream(filename, file_op);
Constructs a FileStream that provides access to the contents of a specified
file. `file_op` specifies the file operation requested and must be one of
the following:
FileOp.Read
Read data from the file. The file must exist and will be opened in
read-only mode. Any attempt to write to the file will throw a
TypeError.
FileOp.Write
Write data to the file. Be careful: If the file already exists,
its contents will be overwritten. If that behavior is not desired,
use `FileOp.Update` instead.
FileOp.Update
Amend the file. If a file by the specified name doesn't exist, it
will be created. For convenience, the file pointer is initially
placed at the end of the file.
Requesting write access to a file residing in a read-only directory (e.g.,
the system directory `#/`) will throw a TypeError.
FileStream#dispose();
Disposes of the FileStream object, closing the underlying file. Attempting
to the object afterwards will throw an error.
Note: While it's not strictly necessary to call `dispose()` on stream
objects, it may take some time for the garbage collector to get to
them. If there's an active FileStream for a given file, particularly
if the file is opened in write mode, an error may be thrown if you
try to construct another one.
FileStream#fileName [read-only]
Gets the full SphereFS pathname of the underlying file.
FileStream#fileSize [read-only]
Gets the size of the underlying file, in bytes.
FileStream#position [read/write]
Gets or sets the file position, which determines where in the file the next
read or write will start from. Expressed in bytes.
Note: For files opened for writing, it is valid to seek past the end of the
stream. In this case the next write will be at the new position and
the intervening space filled with NUL bytes.
FileStream#read(num_bytes);
Reads data from the file, up to the specified number of bytes, and returns
it as an ArrayBuffer. The file must be opened for reading.
FileStream#write(data);
Writes data to the file and advances the file pointer. `data` should be an
ArrayBuffer, TypedArray or DataView containing the data to be written.
`Font` Object
-------------
The `Font` object specifies a typeface that can be used when drawing text.
Sphere provides a default font which is the same for all games, or you can load
one from an RFN font file.
Font.Default [read-only]
Gets the default engine font. This is the font used for the FPS counter
and system messages.
new Font(filename);
Constructs a Font object from a font file. Currently only the Sphere RFN
font format is supported.
Font#fileName [read-only]
Gets the full SphereFS pathname of the file used to construct this Font
object.
Font#height [read-only]
Gets the line height, in pixels, for text rendered using this font.
Font#drawText(surface, x, y, text[, color[, wrap_width]]);
Renders `text` to the specified surface at (x,y). `color` defaults to
Color.White if not provided, and `wrap_width` specifies the width in which
to constrain the text. If `wrap_width` is not provided, no wrapping is
performed.
Font#getTextSize(text, wrap_width);
Gets the size, in pixels, of `text` if it were rendered by Font:drawText()
with the specified wrap width. Return value is an object with `width` and
`height` properties.
Font#wordWrap(text, wrap_width);
Wraps `text` as if it were drawn with Font#drawText() using the specified
wrap width. Returns an array of strings, representing the lines in the
wrapped text.
When drawing large amounts of word-wrapped text every frame, for example in
a text box, this function should be used to pre-wrap the text since
performing wrapping calculations every frame can get expensive.
`IndexList` Object
------------------
An `IndexList` contains indices into a vertex list which are stored on the GPU
for fast access at render time. Index lists can be useful if you want to store
all the vertices for a scene in a single `VertexList` and construct different
shapes from it. The index list specifies which vertices from the list to use
to create a shape.
new IndexList(indices);
Constructs a new index list from `indices`, an array of integers in the
range [0,65535]. If `indices` is not an array or any element is not a
number in the above range, an error will be thrown.
Note: The list of indices stored on the GPU can't be modified later. If
you want to upload a new set of indices, you must construct a new
`IndexList`.
`JobToken` Object
-----------------
A JobToken represents a job queued using one of the `Dispatch` functions above.
When queuing a job, you must keep a reference to the token if you want to be
able to manage the job later.
JobToken#cancel();
Cancels the dispatch job associated with this token. If the job was queued
using either `Dispatch.now()` or `Dispatch.later()` and has already started
running, calling this has no effect.
JobToken#pause();
Pauses the job. Paused jobs will not run, but do keep the event loop alive
and can be resumed at any time without the need to dispatch a new job.
JobToken#resume();
Resumes the job associated with this token after it's been paused with
JobToken#pause(). If the job is not currently paused, this does nothing.
`Joystick` Object
-----------------
Joystick.Null [read-only]
Gets the null joystick. When polled, a null joystick returns neutral
values for all inputs. Joystick.Null can be used in place of a real
Joystick object to simplify input code.
Joystick.getDevices();
Gets an array of Joystick objects, one for each connected gamepad or
joystick.
Joystick#name [read-only]
Gets the name of the device, as reported by the Allegro backend. Xbox
controllers are reported as "XInput Joystick <n>"
Joystick#numAxes [read-only]
Gets the number of analog axes supported by the device.
Joystick#numButtons [read-only]
Gets the number of buttons supported by the device.
Joystick#getPosition(axisID);
Polls the device and gets the current position along the specified analog
axis. To get the number of axes supported by a device, use the `numAxes`
property.
Note: Axes are numbered sequentially, starting from 0. Which physical axis
is associated with any given axis ID will vary from device to device.
For gamepads with analog sticks, though, it's generally a safe bet
that the primary analog stick will be mapped to the first two axes.
Joystick#isPressed(buttonID);
Polls the device and returns true if the specified button is currently
depressed. To get the number of buttons supported by a device, use the
`numButtons` property.
Note: Buttons are numbered sequentially, starting from 0. As with axes,
which physical button is associated with any given button ID will
vary from device to device.
`Keyboard` Object
-----------------
What would a game be without the ability for the player to control it? The
`Keyboard` object allows your game to accept input via the keyboard, the most
common input method for a PC game.
Key [enumeration]
Specifies a keyboard key. Can be one of the following:
Key.Alt
Key.AltGr
Key.Apostrophe
Key.Backslash
Key.Backspace
Key.CapsLock
Key.CloseBrace
Key.Comma
Key.Delete
Key.Down
Key.End
Key.Enter
Key.Equals
Key.Escape
Key.F1
Key.F2
Key.F3
Key.F4
Key.F5
Key.F6
Key.F7
Key.F8
Key.F9
Key.F10
Key.F11
Key.F12
Key.Home
Key.Hyphen
Key.Insert
Key.LCtrl
Key.LShift
Key.Left
Key.NumLock
Key.OpenBrace
Key.PageDown
Key.PageUp
Key.Period
Key.RCtrl
Key.RShift
Key.Right
Key.ScrollLock
Key.Semicolon
Key.Slash
Key.Space
Key.Tab
Key.Tilde
Key.Up
Key.A
Key.B
Key.C
Key.D
Key.E
Key.F
Key.G
Key.H
Key.I
Key.J
Key.K
Key.L
Key.M
Key.N
Key.O
Key.P
Key.Q
Key.R
Key.S
Key.T
Key.U
Key.V
Key.W
Key.X
Key.Y
Key.Z
Key.D1
Key.D2
Key.D3
Key.D4
Key.D5
Key.D6
Key.D7
Key.D8
Key.D9
Key.D0
Key.NumPad1
Key.NumPad2
Key.NumPad3
Key.NumPad4
Key.NumPad5
Key.NumPad6
Key.NumPad7
Key.NumPad8
Key.NumPad9
Key.NumPad0
Key.NumPadEnter
Key.Add
Key.Decimal
Key.Divide
Key.Multiply
Key.Subtract
Note: Keys D0-D9 refer to the row of numbers above the letter keys and
below the function keys, while NumPad0-NumPad9 refer to the numbers
on the numeric keypad.
Keyboard.Default [read-only]
Gets a `Keyboard` object for the default keyboard device.
Note: miniSphere currently only supports a single keyboard.
Keyboard#capsLock [read-only]
Keyboard#numLock [read-only]
Keyboard#scrollLock [read-only]
Gets the state of the corresponding lock key. true if the lock is on,
false if not.
Keyboard#charOf(key[, shifted]);
Gets the character(s) that would be generated if a specified key is pressed
on this keyboard. For example, Key.A becomes "a" (or "A" if shifted).
`shifted` specifies whether to act as if the Shift key is pressed and
defaults to `false`.
An empty string is returned if the specified key is not associated with a
character (a modifier key, for example).
Keyboard#clearQueue();
Removes all keys from the keyboard queue. If another key is not pressed
in the interim, the next getKey() will return null.
Keyboard#getKey();
Gets the next key in the keyboard queue, or null if the queue is empty.
Keyboard#isPressed(key);
Returns true if the user is currently pressing the specified key. `key`
should be a member of the Key enumeration.
`Mixer` Object
--------------
Mixers are used to group related audio together and adjust their parameters as
a class; this is useful, for example, for implementing global volume controls
in your game.
Mixer.Default [read-only]