ANT.wasm is a way to make games in WebAssembly and have it run in the ANTRequest Ecosystem. The guiding principle is simple: it either runs in WebAssembly, or it doesnt run at all.
to use ANT.wasm you can use This Specification to insure interoperability. If you do not Like where this is going please fork.
this document written on is Semantic version 0.0.2. this document is self-published independently.
i am still Figuring things out. this is not final design and might be vague, impossible, or otherwise not implementable. im still seeking to bring this closer to my vision.
As a refresher here are some concepts you need to know.
f32: a float 32.
f64: a float 64.
i32: an int 32.
i64: an int 64.
All drawing coordinates and mouse coordinates are in CSS pixels, as defined by the CSS Reference Pixel.
1 CSS pixel is the visual angle of one pixel on a device with a pixel density of 96dpi at arm's length. Edges MUST scale coordinates appropriately for the display's physical pixel density. Games SHOULD NOT assume that 1 CSS pixel equals 1 device pixel.
For example, on a Retina display (2x scaling), a rectangle drawn at draw_rect(0, 0, 100, 100)
will occupy 200 device pixels. The game does not need to account for this scaling—the Edge handles it.
the Following Formats MUST be supported.
image/webpvideo/webmaudio/webmapplication/jsonapplication/ziptext/plainthe Following Formats MAY be supported too.
image/pngimage/aviftext/markdownaudio/mpegvideo/mp4image/svg+xmlYour Wasm package is called a game. Your Game has the following phases. in order of appearance
| Name | Description |
|---|---|
| Loading Phase | Here is where the Edge loads and verifies the ANT.zip. if it is marked as Untrusted the Edge MUST abort proceeding. |
| Initialization Phase | Here is where you Initialize your game before it runs. |
| game Phase | Here is where you let the player play. this is activated by calling
start_game.
|
| closing Phase | Here is where the Edge cleans up the game's resources. |
It is assumed Imports and Exports are called to the invoking Wasm Module unless otherwise stated.
[[VariableType]] is an internal variable type. wasm doesnt support strings so
[[String]] is for the specification only is what i mean.
[[%FunctionName%]] is an internal function name. they MUST NOT be exposed to
any Wasm Module.
$Variablename is an internal variable name used only in the internal function.
they are unobservable outside it. even if they share the same name
If any of the following Invariants are violated, that is a spec bug.
[[%StringFromBytes%]] (of: [[FileHandler]], ptr:
i32, len: i32): [[String]]Do the following in order
GENERIC_FAILURE (-1).
[[%BytesFromString%]] (string: [[String]]): i32Do the following in order
host_malloc is not exported return WASM_PORT_MISSING (-7).
host_malloc with
$length.
[[%LoadModule%]] (path: [[String]],
Imports: [[ImportLibrary]])>: i32Do the following in order
INVALID_GAME_STATE_ERROR (-4).
RESOLUTION_ERROR (-3).
RESOLUTION_ERROR (-3).
on_module_load if
present with ($wasmModulesLoaded as ModuleId).
All Wasm Modules MUST expose or be exposed to the following functions, the Basic Global Library's WASM namespace is BasicGlobalLibrary.
| Name | Types | Import/Export | Description |
|---|---|---|---|
host_malloc
| (bytes: i32): i32
| Export | host_malloc MUST return a positive number indicating a pointer ($pointer)
on that Wasm's Linear Memory, $pointer until ($pointer + bytes)
MUST be free for the Edge to store whatever is the Edge needs. If that fails or there isnt memory to
allocate to the Edge, Return the appropriate Error Code.
|
on_module_load
| (ModuleId: i32): void
| Export | called when the Wasm Module is loaded via
load_module.
|
tick
| (delta: f32): void
| Export | for as long as the game is running, this export is called with with delta as the timedelta since the previous call in milliseconds. |
current_mouse_press
| (): i32
| Import | The Mouse Key Pressed currently. a bitwise flag of the following below |
current_mouse_x
| (): i64
| Import | The X coordinate of the Mouse. 0, 0 is the top left. X goes positive the more right the mouse is. |
current_mouse_y
| (): i64
| Import | The X coordinate of the Mouse. 0, 0 is the top left. Y goes positive the more down the mouse is. |
current_mouse_wheel
| (): i32
| Import | The Mouse's wheel direction. as bitwise flag of the following below |
on_key_down
| (keycode: i32): i32
| Export | MUST be called everytime a keyboard key is pressed. Key codes MUST follow the USB HID Usage Tables specification, using the Usage IDs from the Keyboard/Keypad page (0x07). Reference: USB HID Usage Tables v1.12, published by the USB Implementers Forum. |
on_key_up
| (keycode: i32): i32
| Export | MUST be called everytime a keyboard key is released.
Key codes MUST follow the USB HID Usage Tables specification, using the Usage IDs from the Keyboard/Keypad page (0x07). Reference: USB HID Usage Tables v1.12, published by the USB Implementers Forum. |
| Name | Bitwise |
|---|---|
| Left Mouse Button | 1, (1 << 0) (One) |
| Right Mouse Button | 2, (1 << 1) (Two) |
| Mouse Wheel Button | 4, (1 << 2) (Four) |
| Name | Bitwise |
|---|---|
| Not Scrolling | 0 (Zero)
|
| Scrolling Up | 8, (1 << 3) (Eight) |
| Scrolling Down | 16, (1 << 4) (SixTeen) |
All Wasm Modules MUST expose or be exposed to the following functions too, the
Basic Paint Library's WASM namespace is screenpaint.
| Name | Types | Import/Export | Description |
|---|---|---|---|
draw_rect
| (x: i32, y: i32, w: i32, h: i32, color:
i32): i32
| Import | If Game has not Started Return INVALID_GAME_STATE_ERROR (-4). draw a Rectangle at the offset
x (the x/horizontal coordinate), y (the y/vertical coordinate) from the top
left which is 0, 0 with color as RGBA8 color. the rectangle MUST be w (width),
h (height) in size. Return GENERIC_SUCCESS (0).
|
draw_path
| (ptr: i32, len: i32, fillColor: i32, strokeColor:
i32, strokeWidth: i32): i32
| Import |
|
load_texture
| (ptr: i32, len: i32): i32
| Import | Do the following in order
|
draw_texture
| (texture_handler: i32, x: i32, y: i32, w: i32,
h: i32, deg: i32): i32
| Import | Do the following in order
|
texture_css_height
| (texture_handler: i32): i32
| Import | Do the following in order
|
texture_css_width
| (texture_handler: i32): i32
| Import | Do the following in order
|
texture_free
| (texture_handler: i32): i32
| Import | Do the following in order
|
[[TextureHandler]]A [[TextureHandler]] is an Edge-Defined opaque identifier representing an image. It MUST:
texture_free is called.
texture_free, but the Edge MUST clean up any remaining open handlers at game termination.
A Main is a wasm file that is called after a Core. it is the main function.
If we are talking about User Generated Content games, A Core is the actual Game where A Main is the core for a sharable package a user has created.
A Main MUST expose or be exposed to the following functions, the Main's WASM namespace is
MainModule.
| Name | Types | Import/Export | Description |
|---|---|---|---|
load_module
| (ptr: i32, len: i32): i32
| Import | Do the following in order
|
start_game
| (width: i32, height: i32): void
| Import | Do the following in order
|
A Core is a wasm file that is first called. it is the engine so games can stay self-contained
within their ANT.zip. the core MUST live at
"/core.wasm" (case-sensitive) ziproot path.
If we are talking about User Generated Content games, A Core is the actual Game where A Main is the core for a sharable package a user has created.
A Core MUST expose or be exposed to the following functions, the Core's WASM namespace is
CoreModule.
| Name | Types | Import/Export | Description |
|---|---|---|---|
load_module_core
| (ptr: i32, len: i32): i32
| Import | Do the following in order
|
load_main
| (): void
| Import | Do the following in order
|
the File System Extension is an Extension of the Basic Global Library, anywhere where the Basic Global Library is imported or exported an Edge SHOULD choose to import this too. if they do not wish to implement it then the Methods not implemented MUST be stubbed.
the File System Extension MUST be everywhere it is supposed to be or nowhere, implementing it partially (unless
otherwise specified) is a violation of this specification. when it is implemented the Wasm
Module MUST be exposed to the following functions, the WASM namespace is FileExtensionV1.
the Game is the Same Game if the sha256 of the ANT.json is the same. the game MUST be verified to be the same game.
| Name | Types | Import/Export | Description |
|---|---|---|---|
file_open
| (ptr: i32, len: i32): i32
| Import | Do the following in order
|
file_read
| (file_handler: i32, wasm_ptr: i32, file_ptr:
i32, file_len: i32): i32
| Import | Do the following in order
|
file_write
| (file_handler: i32, wasm_ptr: i32, file_ptr: i32,
wasm_len: i32): i32
| Import | Do the following in order
|
file_type
| (ptr: i32, len: i32): i32
| Import | Do the following in order
|
file_size
| (file_handler: i32): i64
| Import | Do the following in order
|
file_close
| (file_handler: i32): i32
| Import | Do the following in order
|
file_mtime
| (file_handler: i32): i64
| OPTIONAL Import | Do the following in order
|
Virtual Directories are a security measure to not allow games to write anywhere on the user's file system. currently there are 2
| Name | Permissions | Description |
|---|---|---|
/user/
| ReadWrite | The Game's User Directory. for save files, photos, and anything the game wants to save. |
/game/
| ReadOnly | The Game's Asset Directory. Direct to the ANTzip. |
[[FileHandler]]An [[FileHandler]] is an Edge-Defined opaque identifier representing an open file. It MUST:
file_close is called.
file_close, but the Edge MUST clean up any remaining open handlers at game termination.
$permissions property with values being ReadWrite or
ReadOnly
Edges SHOULD impose limits on:
If a limit is exceeded, the Edge SHOULD return NO_MORE_MEMORY_ERROR (-6)
or LACKS_PERMS (-8) as appropriate.
the Screen Capture Api is an Extension of the Basic Global Library, anywhere where the Basic Global Library is imported or exported an Edge SHOULD choose to import this too. if they do not wish to implement it then the Methods not implemented MUST be stubbed.
the Screen Capture Api Extension MUST only be present if the File System Extension is present.
the Screen Capture Api Extension MUST be everywhere it is supposed to be or nowhere, implementing it partially
(unless otherwise specified) is a violation of this specification. when it is implemented the Wasm Module MUST be exposed to the following functions, the WASM namespace is screenvideoV1.
| Name | Types | Import/Export | Description |
|---|---|---|---|
take_screenshot
| (): i32
| Import | Do the following in order
|
start_video_recording
| (): i32
| Import | Do the following in order
|
take_video_snapshot
| (video_handler: i32): i32
| Import | Do the following in order
|
stop_video_recording
| (video_handler: i32): i32
| Import | Do the following in order
|
[[VideoHandler]]An [[VideoHandler]] is an Edge-Defined opaque identifier representing an active video recording session. It MUST:
stop_video_recording is called.
stop_video_recording.
[[Canvas]]A [[Canvas]] is the rendering surface initialized by start_game.
It has the following internal properties:
the Datetime Api is an Extension of the Basic Global Library, anywhere where the Basic Global Library is imported or exported an Edge SHOULD choose to import this too. if they do not wish to implement it then the Methods not implemented MUST be stubbed.
the Datetime Api Extension MUST be everywhere it is supposed to be or nowhere, implementing it partially
(unless otherwise specified) is a violation of this specification. when it is implemented the Wasm Module MUST be exposed to the following functions, the WASM namespace is antdatetime.
| Name | Types | Import/Export | Description |
|---|---|---|---|
utc_now_ms
| (): i64
| Import | Return the milliseconds since the unix epoch. the Edge MAY round the value to reduce fingerprinting. If rounding is applied, the rounded value MUST still be consistent with the actual mtime (e.g., rounded to nearest hour, not arbitrary). |
utc_offset_ms_at
| (timestamp: i64): i64
| Import | Return the utc offset in milliseconds at that timestamp in the user's local time. an Edge SHOULD consider rounding it to the nearest 15, 30, or 60 minutes to reduce fingerprinting. an Edge MAY choose to always return 0 instead, representing UTC. Positive for East, Negative for West. |
Any of the following methods not chosen to be implemented MUST return WASM_PORT_MISSING (-7)
without doing anything. (including but not limited to)
FileExtensionV1.file_openFileExtensionV1.file_readFileExtensionV1.file_typeFileExtensionV1.file_sizeFileExtensionV1.file_writeFileExtensionV1.file_mtimescreenvideoV1.start_video_recordingscreenvideoV1.stop_video_recordingscreenvideoV1.take_video_snapshotscreenvideoV1.take_screenshotantdatetime.utc_offset_ms_atantdatetime.utc_now_msthe following table will list the error codes as negative numbers, their canonical upper snakecase name, and their description.
ANTRequest would like to reserve -1 to -255 for the ANTRequest Specifications. while allowing the community to use -256 to -2 147 483 648 (i32 limit) however they like.
| Code | UPPER_CASE_NAME | Description |
|---|---|---|
0 (Zero) | GENERIC_SUCCESS | An Operation completed without any error. |
-1 (Negative One) | GENERIC_FAILURE | A Generic Failure. |
-2 (Negative Two) | PATH_RESOLUTION_ERROR | A path cant be resolved due to any reason, including bt not limited to
|
-3 (Negative Three) | RESOLUTION_ERROR | A Path requiring a Wasm Module, but doesnt point to a valid compilable Wasm Module. |
-4 (Negative Four) | INVALID_GAME_STATE_ERROR | the game is in a invalid state. formerly GAME_HASNT_STARTED_YET_ERROR (-4) and GAME_IS_RUNNING_ERROR (-5) |
-5 (Negative Five) | RESERVED | reserved for future use. |
-6 (Negative Six) | NO_MORE_MEMORY_ERROR | The Operation requires more memory but it cant be granted. |
-7 (Negative Seven) | WASM_PORT_MISSING | An Import or Export is missing. |
-8 (Negative Eight) | LACKS_PERMS | The Wasm Module lacks the permissions to perform this action. (or the host lacks the permissions too) |
-9 (Negative Nine) | SCREEN_DISPLAY_ERROR | An error at the Screen's display happened for any reason. |